/*
  作者：不正经绣才
  日期：2025.8.26
*/
const app = getApp();
const { logInfo, logWarn, logError } = require('../../utils/log.js');

Page({
  data: {
    navHeight: 44, // 导航栏高度
    statusBarHeight: 20, // 状态栏高度
    capsuleButtonInfo: null, // 胶囊按钮信息
    wheelName: '',
    result: '???',
    wheelItems: [],
    spinning: false,
    canvas: null,
    ctx: null,
    canvasWidth: 0,
    canvasHeight: 0,
    // 粒子系统相关数据
    particles: [], // 粒子数组
    showParticles: false, // 是否显示粒子效果
    resultSectorIndex: -1, // 结果扇区索引（用于突出显示）
    // 音频上下文对象（用于播放停止提示音）
    audioCtx: null ,
    showSettingsMenu: false,
    soundEnabled: true, // 默认开启声音
    // 模式切换相关数据
    currentMode: 'wheel', // 当前激活的模式：wheel/coin/cards/muyu/fortune
    currentModeIndex: 0, // 当前模式索引
    displayModeIndex: 0, // 显示的模式索引（用于中间按钮文字显示）
    modes: ['wheel', 'cards', 'fortune', 'coin', 'muyu'], // 模式列表
    modeNames: ['👉 转盘🎯', '👉 翻牌子🃏', '👉 幸运抽签📜', '👉 抛硬币🪙', '👉 减压敲🪘'], // 模式显示名称
    // 抛硬币相关数据
    coinResult: '',
    coinFlipping: false,
    coinCanvas: null,
    coinCtx: null,
    coinAudioCtx: null, // 抛硬币音效上下文

    // 翻牌子相关数据
    cardsResult: '',
    cardsCanvas: null,
    cardsCtx: null,
    cards: [], // 牌子数据数组
    flippedCards: [], // 已翻开的牌子索引
    cardsAudioCtx: null, // 翻牌子音效上下文
    // 减压敲相关数据
    muyuCanvas: null,
    muyuCtx: null,
    gongde: 0, // 累计功德值
    isKnocking: false, // 是否正在敲击
    showGongdeTip: false, // 是否显示功德+1提示
    muyuAudioCtx: null, // 木鱼敲击音效上下文
    // 幸运抽签相关数据
    fortuneCanvas: null,
    fortuneCtx: null,
    isShaking: false, // 是否正在摇动签筒
    fortuneResult: '', // 抽签结果
    showFortuneStick: false, // 是否显示签文
    fortuneAudioCtx: null, // 幸运抽签音效上下文
    // 背景动画相关数据
    backgroundAnimationActive: false, // 背景动画是否激活
    backgroundAnimationTimer: null, // 背景动画定时器
    starSpeedMultiplier: 1, // 星星速度倍数
    
    // 幸运抽签动画参数
    shakeIntensity: 1.0, // 摇动强度
    shakeSpeed: 1.0, // 摇动速度
    
    // 每日首次使用状态
    hasCoinToday: false,
    hasCardsToday: false,
    hasMuyuToday: false,
    hasFortuneToday: false
  },

  onLoad: function () {
    this.initCanvas();
    this.initAudio();
    this.initCards();
    this.initMuyu();
    this.initFortune();
    this.initBackgroundAnimation();
  },

  initCanvas: function () {
    const query = wx.createSelectorQuery();
    query.select('#wheelCanvas').fields({ node: true, size: true }).exec((res) => {
      const canvas = res[0].node;
      const ctx = canvas.getContext('2d');
      this.setData({
        canvas: canvas,
        ctx: ctx,
        canvasWidth: canvas.width,
        canvasHeight: canvas.height
      });
      this.drawWheel();
    });
  },

  initAudio: function () {
    this.setData({
      audioCtx: wx.createInnerAudioContext()
    });
  },

  initCards: function () {
    const query = wx.createSelectorQuery();
    query.select('#cardsCanvas').fields({ node: true, size: true }).exec((res) => {
      const canvas = res[0].node;
      const ctx = canvas.getContext('2d');
      this.setData({
        cardsCanvas: canvas,
        cardsCtx: ctx,
        cards: [
          { text: 'A', color: '#ff7675' },
          { text: 'B', color: '#74b9ff' },
          { text: 'C', color: '#55efc4' },
          { text: 'D', color: '#ffeaa7' }
        ]
      });
      this.drawCards();
    });
  },

  initMuyu: function () {
    const query = wx.createSelectorQuery();
    query.select('#muyuCanvas').fields({ node: true, size: true }).exec((res) => {
      const canvas = res[0].node;
      const ctx = canvas.getContext('2d');
      this.setData({
        muyuCanvas: canvas,
        muyuCtx: ctx
      });
      this.drawMuyu();
    });
  },

  initFortune: function () {
    const query = wx.createSelectorQuery();
    query.select('#fortuneCanvas').fields({ node: true, size: true }).exec((res) => {
      const canvas = res[0].node;
      const ctx = canvas.getContext('2d');
      this.setData({
        fortuneCanvas: canvas,
        fortuneCtx: ctx
      });
      this.drawFortune();
    });
  },

  initBackgroundAnimation: function () {
    this.setData({
      backgroundAnimationActive: true
    });
    this.startBackgroundAnimation();
  },

  startBackgroundAnimation: function () {
    const ctx = wx.createCanvasContext('backgroundCanvas');
    const starCount = 100;
    const stars = [];
    for (let i = 0; i < starCount; i++) {
      stars.push({
        x: Math.random() * 375,
        y: Math.random() * 667,
        size: Math.random() * 2 + 1,
        speed: Math.random() * 2 + 1
      });
    }
    const animate = () => {
      ctx.clearRect(0, 0, 375, 667);
      stars.forEach((star) => {
        ctx.beginPath();
        ctx.arc(star.x, star.y, star.size, 0, 2 * Math.PI);
        ctx.fillStyle = '#ffffff';
        ctx.fill();
        star.y += star.speed * this.data.starSpeedMultiplier;
        if (star.y > 667) {
          star.y = 0;
          star.x = Math.random() * 375;
        }
      });
      ctx.draw();
      if (this.data.backgroundAnimationActive) {
        setTimeout(animate, 16); // 约60fps
      }
    };
    animate();
  },

  drawCards: function () {
    const ctx = this.data.cardsCtx;
    const width = this.data.cardsCanvas.width;
    const height = this.data.cardsCanvas.height;
    const cardWidth = width / 2 - 20;
    const cardHeight = height / 2 - 20;

    this.data.cards.forEach((card, index) => {
      const x = (index % 2) * (cardWidth + 20) + 10;
      const y = Math.floor(index / 2) * (cardHeight + 20) + 10;
      ctx.beginPath();
      ctx.rect(x, y, cardWidth, cardHeight);
      ctx.fillStyle = card.color;
      ctx.fill();
      ctx.fillStyle = '#ffffff';
      ctx.font = '24px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(card.text, x + cardWidth / 2, y + cardHeight / 2);
    });
  },

  drawMuyu: function () {
    const ctx = this.data.muyuCtx;
    const width = this.data.muyuCanvas.width;
    const height = this.data.muyuCanvas.height;

    ctx.beginPath();
    ctx.arc(width / 2, height / 2, 50, 0, 2 * Math.PI);
    ctx.fillStyle = '#ff7675';
    ctx.fill();

    ctx.beginPath();
    ctx.arc(width / 2 - 20, height / 2 - 20, 10, 0, 2 * Math.PI);
    ctx.fillStyle = '#ffffff';
    ctx.fill();

    ctx.beginPath();
    ctx.arc(width / 2 + 20, height / 2 - 20, 10, 0, 2 * Math.PI);
    ctx.fillStyle = '#ffffff';
    ctx.fill();

    ctx.beginPath();
    ctx.moveTo(width / 2 - 20, height / 2 + 20);
    ctx.lineTo(width / 2 + 20, height / 2 + 20);
    ctx.strokeStyle = '#ffffff';
    ctx.stroke();
  },

  drawFortune: function () {
    const ctx = this.data.fortuneCtx;
    const width = this.data.fortuneCanvas.width;
    const height = this.data.fortuneCanvas.height;

    ctx.beginPath();
    ctx.rect(10, 10, width - 20, height - 20);
    ctx.fillStyle = '#ff7675';
    ctx.fill();

    ctx.fillStyle = '#ffffff';
    ctx.font = '16px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('点击摇动签筒', width / 2, height / 2);
  },

  playStopSound: function () {
    if (this.data.soundEnabled) {
      this.data.audioCtx.src = '/sounds/stop.mp3';
      this.data.audioCtx.play();
    }
  },

  showParticles: function () {
    const ctx = this.data.ctx;
    const width = this.data.canvasWidth;
    const height = this.data.canvasHeight;
    const centerX = width / 2;
    const centerY = height / 2;

    const particleCount = 50;
    const particles = [];

    for (let i = 0; i < particleCount; i++) {
      particles.push({
        x: centerX,
        y: centerY,
        size: Math.random() * 2 + 1,
        speed: Math.random() * 2 + 1,
        angle: Math.random() * 2 * Math.PI
      });
    }

    this.setData({
      particles: particles
    });

    const animate = () => {
      ctx.clearRect(0, 0, width, height);
      this.drawWheel();
      this.data.particles.forEach((particle) => {
        ctx.beginPath();
        ctx.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI);
        ctx.fillStyle = '#ffffff';
        ctx.fill();
        particle.x += particle.speed * Math.cos(particle.angle);
        particle.y += particle.speed * Math.sin(particle.angle);
        particle.size -= 0.05;
        if (particle.size <= 0) {
          particle.x = centerX;
          particle.y = centerY;
          particle.size = Math.random() * 2 + 1;
          particle.speed = Math.random() * 2 + 1;
          particle.angle = Math.random() * 2 * Math.PI;
        }
      });
      ctx.draw();

      if (this.data.showParticles) {
        setTimeout(animate, 16); // 约60fps
      }
    };

    animate();
  },

  toggleSettingsMenu: function () {
    this.setData({
      showSettingsMenu: !this.data.showSettingsMenu
    });
  },

  toggleSound: function () {
    this.setData({
      soundEnabled: !this.data.soundEnabled
    });
  },

  changeMode: function (e) {
    const modeIndex = parseInt(e.currentTarget.dataset.index);
    this.setData({
      currentModeIndex: modeIndex,
      displayModeIndex: modeIndex,
      currentMode: this.data.modes[modeIndex]
    });
  },

  flipCoin: function () {
    if (this.data.coinFlipping) return;
    this.setData({
      coinFlipping: true,
      coinResult: ''
    });

    const randomValue = Math.random();
    const result = randomValue < 0.5 ? '正面' : '反面';

    const ctx = this.data.coinCtx;
    const width = this.data.coinCanvas.width;
    const height = this.data.coinCanvas.height;

    let startTime = Date.now();
    const flipDuration = 1000; // 1 second

    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / flipDuration, 1);

      ctx.clearRect(0, 0, width, height);
      if (progress < 0.5) {
        ctx.beginPath();
        ctx.arc(width / 2, height / 2, 50, 0, 2 * Math.PI);
        ctx.fillStyle = '#ff7675';
        ctx.fill();
      } else {
        ctx.beginPath();
        ctx.arc(width / 2, height / 2, 50, 0, 2 * Math.PI);
        ctx.fillStyle = '#74b9ff';
        ctx.fill();
      }

      if (progress < 1) {
        setTimeout(animate, 16); // 约60fps
      } else {
        this.setData({
          coinFlipping: false,
          coinResult: result
        });
        this.playCoinSound();
      }
    };

    animate();
  },

  playCoinSound: function () {
    if (this.data.soundEnabled) {
      this.data.coinAudioCtx.src = '/sounds/coin.mp3';
      this.data.coinAudioCtx.play();
    }
  },

  flipCard: function (e) {
    const cardIndex = parseInt(e.currentTarget.dataset.index);
    if (this.data.flippedCards.includes(cardIndex)) return;

    this.setData({
      flippedCards: [...this.data.flippedCards, cardIndex]
    });

    this.playCardSound();

    if (this.data.flippedCards.length === this.data.cards.length) {
      const result = this.data.cards.map((card, index) => {
        return this.data.flippedCards.includes(index) ? card.text : '?';
      }).join(' ');
      this.setData({
        cardsResult: result
      });
    }
  },

  playCardSound: function () {
    if (this.data.soundEnabled) {
      this.data.cardsAudioCtx.src = '/sounds/card.mp3';
      this.data.cardsAudioCtx.play();
    }
  },

  knockMuyu: function () {
    if (this.data.isKnocking) return;
    this.setData({
      isKnocking: true,
      showGongdeTip: true,
      gongde: this.data.gongde + 1
    });

    this.playMuyuSound();

    setTimeout(() => {
      this.setData({
        isKnocking: false,
        showGongdeTip: false
      });
    }, 500);
  },

  playMuyuSound: function () {
    if (this.data.soundEnabled) {
      this.data.muyuAudioCtx.src = '/sounds/muyu.mp3';
      this.data.muyuAudioCtx.play();
    }
  },

  shakeFortune: function () {
    if (this.data.isShaking) return;
    this.setData({
      isShaking: true,
      showFortuneStick: false,
      fortuneResult: ''
    });

    const ctx = this.data.fortuneCtx;
    const width = this.data.fortuneCanvas.width;
    const height = this.data.fortuneCanvas.height;

    let startTime = Date.now();
    const shakeDuration = 2000; // 2 seconds

    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / shakeDuration, 1);

      ctx.clearRect(0, 0, width, height);
      ctx.beginPath();
      ctx.rect(10, 10, width - 20, height - 20);
      ctx.fillStyle = '#ff7675';
      ctx.fill();

      ctx.fillStyle = '#ffffff';
      ctx.font = '16px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('摇动中...', width / 2, height / 2);

      if (progress < 1) {
        setTimeout(animate, 16); // 约60fps
      } else {
        this.setData({
          isShaking: false,
          showFortuneStick: true,
          fortuneResult: result
        });
        this.playFortuneSound();
      }
    };

    animate();
  },

  playFortuneSound: function () {
    if (this.data.soundEnabled) {
      this.data.fortuneAudioCtx.src = '/sounds/fortune.mp3';
      this.data.fortuneAudioCtx.play();
    }
  },

  onLoad(options) {
    // 检查是否有模式参数（URL参数方式）
    let targetMode = null;
    if (options && options.mode !== undefined) {
      targetMode = parseInt(options.mode);
      logInfo(`接收到URL模式参数：${targetMode}`);
    }
    
    // 检查全局数据中的目标模式（从个人中心跳转）
    if (targetMode === null && app.globalData.targetMode !== undefined) {
      targetMode = app.globalData.targetMode;
      logInfo(`接收到全局模式参数：${targetMode}`);
      
      // 清除全局数据，避免重复切换
      app.globalData.targetMode = undefined;
      app.globalData.targetModeName = undefined;
    }
    
    if (targetMode !== null) {
      // 设置目标模式
      this.setData({
        currentMode: this.data.modes[targetMode] || 'wheel',
        currentModeIndex: targetMode || 0,
        displayModeIndex: targetMode || 0
      });
    } else {
      // 默认状态为转盘模式
      this.setData({
        currentMode: 'wheel',
        currentModeIndex: 0,
        displayModeIndex: 0
      });
    }
    
    // 初始化转盘数据
    this.initWheelData();
    
    // 初始化提示音（页面加载时创建，避免播放延迟）
    this.initAudioContext();
    
    // 初始化木鱼敲击音效
    this.initMuyuAudioContext();
    
    // 初始化抛硬币音效
    this.initCoinAudioContext();

    // 初始化翻牌子音效
    this.initCardsAudioContext();

    // 初始化洗牌音效
    this.initShuffleAudioContext();

    // 初始化幸运抽签音效
    this.initFortuneAudioContext();

    // 加载功德值
    const gongde = wx.getStorageSync('gongde') || 0;
    this.setData({ gongde });

    // 加载每日首次使用状态
    this.loadDailyModeStatus();

    this.setData({
      spinDuration: app.globalData.spinDuration || 5,
      vibrateEnabled: app.globalData.vibrateEnabled !== undefined ? app.globalData.vibrateEnabled : true,
      soundEnabled: app.globalData.soundEnabled !== undefined ? app.globalData.soundEnabled : true
    });
  },

  onShow() {
    // 页面切换时重新加载数据
    logInfo('首页onShow - 开始刷新数据');
    
    // 检查全局数据中的目标模式（从个人中心跳转）
    if (app.globalData.targetMode !== undefined) {
      const targetMode = app.globalData.targetMode;
      logInfo(`onShow检测到目标模式：${targetMode}`);
      
      // 设置目标模式
      this.setData({
        currentMode: this.data.modes[targetMode] || 'wheel',
        currentModeIndex: targetMode || 0,
        displayModeIndex: targetMode || 0
      });
      
      // 清除全局数据，避免重复切换
      app.globalData.targetMode = undefined;
      app.globalData.targetModeName = undefined;
      
      // 切换到对应模式
      this.switchToMode(targetMode);
      logInfo('首页onShow - 模式切换完成');
      return; // 早退出，避免重复初始化
    }
    
    // 重新初始化转盘数据（确保数据是最新的）
    this.initWheelData();

    // 重新初始化提示音（页面加载时创建，避免播放延迟）
    this.initAudioContext();
    
    // 重新初始化木鱼敲击音效
    this.initMuyuAudioContext();
    
    // 重新初始化抛硬币音效
    this.initCoinAudioContext();

    // 重新初始化翻牌子音效
    this.initCardsAudioContext();

    // 重新初始化洗牌音效
    this.initShuffleAudioContext();

    // 重新初始化幸运抽签音效
    this.initFortuneAudioContext();

    // 重新加载设置项
    this.setData({
      spinDuration: app.globalData.spinDuration || 5,
      vibrateEnabled: app.globalData.vibrateEnabled !== undefined ? app.globalData.vibrateEnabled : true,
      soundEnabled: app.globalData.soundEnabled !== undefined ? app.globalData.soundEnabled : true
    });
    
    // 重新加载功德值
    const gongde = wx.getStorageSync('gongde') || 0;
    this.setData({ gongde });
    
    // 重新加载每日首次使用状态
    this.loadDailyModeStatus();
    
    // 重新绘制转盘（如果当前是转盘模式）
    if (this.data.currentMode === 'wheel') {
      logInfo('当前为转盘模式，重新绘制转盘');
      // 延迟一下绘制，确保数据更新完成
      setTimeout(() => {
        this.redrawWheel();
      }, 100);
    }
    
    logInfo('首页onShow - 刷新完成');
  },

  // 当页面隐藏时（切换到其他页面）
  onHide() {
    // 清空结果
    this.setData({
      result: '???',
      coinResult: '',
      cardsResult: '',
      showGongdeTip: false
    });
  },

  // 编辑转盘按钮点击事件
  onEditWheel() {
    const currentWheel = getApp().globalData.currentWheel;
    if (currentWheel && currentWheel.id) {
      wx.navigateTo({
        url: `/pages/edit-wheel/edit-wheel?id=${currentWheel.id}`
      });
    } else {
      wx.showToast({
        title: '无法编辑转盘',
        icon: 'none'
      });
    }
  },

  onReady() {
    // 根据当前模式初始化对应的Canvas
    const currentMode = this.data.currentMode;
    if (currentMode === 'wheel') {
      this.ensureWheelDisplay();
    } else {
      // 对于非转盘模式，直接切换到对应模式
      this.switchToMode(this.data.currentModeIndex);
    }
  },

  // 确保转盘显示（首次加载时调用）
  ensureWheelDisplay() {
    // 直接切换到转盘模式
    this.switchToMode(0);
  },

  // 初始化转盘数据
  initWheelData() {
    // 强制从本地存储重新加载allWheels数据，确保获取最新数据
    try {
      const wheels = wx.getStorageSync('wheels') || [];
      app.globalData.allWheels = wheels;
    } catch (e) {
      logError('重新加载allWheels失败', e);
    }
    
    // 1. 优先使用全局当前转盘（如果有效且未被删除）
    let targetWheel = app.globalData.currentWheel;
    
    // 2. 检查当前转盘是否已被删除（删除的转盘不在allWheels列表中）
    if (targetWheel) {
      logInfo('targetWheel=', targetWheel);
      // 验证方式: 检查是否还在全局所有转盘中（推荐）
      const existsInAllWheels = app.globalData.allWheels?.some(wheel => wheel.id === targetWheel.id);
      
      // 如果已被删除，则清空当前目标
      if (!existsInAllWheels) {
        logInfo('当前转盘已被删除，清空引用');
        targetWheel = null;
        // 同时清除全局当前转盘引用
        app.globalData.currentWheel = null;
      }
    }
    
    // 3. 如果全局当前转盘无效，检查本地存储的上次使用记录
    if (!targetWheel) {
      const lastUsedWheelId = wx.getStorageSync('lastUsedWheelId');
      if (lastUsedWheelId) {
        // 从全局所有转盘中查找历史记录对应的转盘
        targetWheel = app.globalData.allWheels?.find(wheel => wheel.id === lastUsedWheelId);
        
        // 检查历史记录的转盘是否已被删除
        if (!app.globalData.allWheels?.some(wheel => wheel.id === lastUsedWheelId)) {
          targetWheel = null;
          wx.removeStorageSync('lastUsedWheelId'); // 清除无效的历史记录
        }
      }
    }
    
    // 4. 如果仍无有效转盘，使用allWheels中的第一个转盘（这应该是默认创建的转盘）
    if (!targetWheel) {
      const allWheels = app.globalData.allWheels || [];
      if (allWheels.length > 0) {
        targetWheel = allWheels[0]; // 使用第一个真实存在的转盘
        logInfo('使用allWheels中的第一个转盘作为默认:', targetWheel);
      } else {
        // 如果连allWheels都是空的，说明有问题，使用热门转盘兜底
        const hotWheels = app.globalData.hotWheels || [];
        if (hotWheels.length > 0) {
          targetWheel = hotWheels[0];
          logInfo('allWheels为空，使用热门转盘兜底:', targetWheel);
        }
      }
    }
    
    if (targetWheel) {
      this.setData({
        wheelName: targetWheel.name,
        wheelItems: targetWheel.items
      });
      // 更新全局当前转盘
      app.globalData.currentWheel = targetWheel;
      // 更新本地存储的上次使用记录（只有真实存在的转盘才保存）
      if (app.globalData.allWheels?.some(wheel => wheel.id === targetWheel.id)) {
        wx.setStorageSync('lastUsedWheelId', targetWheel.id);
      }
    }
  },

  // 创建Canvas上下文
  createCanvasContext() {
    const query = wx.createSelectorQuery();
    query.select('#wheelCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        if (!res[0]) return;
        
        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        const dpr = wx.getSystemInfoSync().pixelRatio;
        
        canvas.width = res[0].width * dpr;
        canvas.height = res[0].height * dpr;
        ctx.scale(dpr, dpr);
        
        this.setData({
          canvas,
          ctx,
          canvasWidth: res[0].width,
          canvasHeight: res[0].height
        });
        
        this.drawWheel();
      });
  },

  // 绘制转盘（支持粒子效果和结果突出）
  drawWheel(rotation = 0) {
    const { ctx, canvasWidth, canvasHeight, wheelItems, showParticles, particles, resultSectorIndex } = this.data;
    if (!ctx) return;
    
    const centerX = canvasWidth / 2;
    const centerY = canvasHeight / 2;
    const radius = Math.min(centerX, centerY) - 1; // 移除了 -10 的边距
    
    // 清空画布
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);
    
    // 计算总权重
    const totalWeight = wheelItems.reduce((sum, item) => sum + item.weight, 0);
    
    // 绘制转盘扇形 - 从12点钟方向开始（-Math.PI/2 对应12点方向）
    let startAngle = rotation - Math.PI / 2;
    wheelItems.forEach((item, index) => {
      const sliceAngle = 2 * Math.PI * item.weight / totalWeight;
      
      // 判断是否为结果扇区，非结果扇区在结束后变暗
      const isDimmed = resultSectorIndex !== -1 && index !== resultSectorIndex;
      const isHighlighted = resultSectorIndex !== -1 && index === resultSectorIndex;
      
      // 绘制扇形
      ctx.beginPath();
      ctx.moveTo(centerX, centerY);
      ctx.arc(centerX, centerY, radius, startAngle, startAngle + sliceAngle);
      ctx.closePath();
      
      // 设置颜色（结果扇区高亮，其他扇区变暗）
      if (isDimmed) {
        // 非结果扇区变暗
        const rgb = this.hexToRgb(item.color);
        ctx.fillStyle = `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.25)`;
      } else if (isHighlighted) {
        // 结果扇区高亮：增加亮度和饱和度
        const rgb = this.hexToRgb(item.color);
        const brighterRgb = this.brightenColor(rgb, 1.4);
        ctx.fillStyle = `rgb(${brighterRgb.r}, ${brighterRgb.g}, ${brighterRgb.b})`;
      } else {
        // 正常状态
        ctx.fillStyle = item.color;
      }
      ctx.fill();

      // 绘制精美边框
      ctx.lineWidth = isHighlighted ? 2 : 1;
      if (isDimmed) {
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';
      } else if (isHighlighted) {
        // 高亮扇区使用金色渐变边框
        const gradient = ctx.createLinearGradient(
          centerX + Math.cos(startAngle) * radius,
          centerY + Math.sin(startAngle) * radius,
          centerX + Math.cos(startAngle + sliceAngle) * radius,
          centerY + Math.sin(startAngle + sliceAngle) * radius
        );
        gradient.addColorStop(0, '#FFD700');
        gradient.addColorStop(0.5, '#FFA500');
        gradient.addColorStop(1, '#FF8C00');
        ctx.strokeStyle = gradient;
      } else {
        // 普通扇区使用白色边框
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.9)';
      }
      ctx.lineJoin = 'round';
      ctx.stroke();
      
      // 为高亮扇区添加内发光效果
      if (isHighlighted) {
        ctx.save();
        ctx.globalCompositeOperation = 'screen';
        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.arc(centerX, centerY, radius * 0.9, startAngle, startAngle + sliceAngle);
        ctx.closePath();
        
        const glowGradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
        glowGradient.addColorStop(0, 'rgba(255, 255, 255, 0.5)');
        glowGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        
        ctx.fillStyle = glowGradient;
        ctx.fill();
        ctx.restore();
      }
      
      // 绘制扇区装饰（小星星）
      if (!isDimmed) {
        ctx.save();
        const midAngle = startAngle + sliceAngle / 2;
        const starRadius = radius * 0.7;
        const starX = centerX + Math.cos(midAngle) * starRadius;
        const starY = centerY + Math.sin(midAngle) * starRadius;
        
        // 绘制小星星
        ctx.fillStyle = isHighlighted ? '#FFFFFF' : 'rgba(255, 255, 255, 0.7)';
        this.drawStar(ctx, starX, starY, 6, '#FFD700');
        ctx.restore();
      }

      // 绘制文字
      ctx.save();
      ctx.translate(centerX, centerY);
      const textAngle = startAngle + sliceAngle / 2 + Math.PI / 2;
      ctx.rotate(textAngle);
      ctx.textAlign = 'center';
      ctx.textBaseline = 'top';

      // 根据高亮状态设置文字样式
      if (isHighlighted) {
        // 高亮扇区的文字更加突出
        ctx.font = 'bold 22px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        
        // 更强的文字描边
        ctx.strokeStyle = 'rgba(0, 0, 0, 0.9)';
        ctx.lineWidth = 2.5;
        // 修改为从弧顶开始的垂直文字排列
        this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
        
        // 高亮文字颜色
        ctx.fillStyle = '#ffffff';
        this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
        
        // 添加文字发光效果
        ctx.shadowColor = 'rgba(255, 255, 255, 1)';
        ctx.shadowBlur = 6;
        this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
        
      } else {
        // 普通文字样式
        ctx.font = 'bold 20px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        
        // 文字描边
        ctx.strokeStyle = isDimmed ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.6)';
        ctx.lineWidth = 1.5;
        // 修改为从弧顶开始的垂直文字排列
        this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);

        ctx.fillStyle = isDimmed ? 'rgba(255, 255, 255, 0.6)' : '#fff';
        this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
      }
      
      // 清除阴影设置
      ctx.shadowColor = 'transparent';
      ctx.shadowBlur = 0;
      ctx.shadowOffsetX = 0;
      ctx.shadowOffsetY = 0;
      
      ctx.restore();

      startAngle += sliceAngle;
    });

    // 绘制粒子效果
    if (showParticles) {
      this.drawParticles(ctx, centerX, centerY, radius);
    }

    // 绘制指针
    this.drawPointer(ctx, centerX, centerY, radius);
    
    // 绘制中心按钮（带立体感的幸运星设计）
    this.drawCenterButton(ctx, centerX, centerY, radius);
  },

  // 绘制垂直文字（每个字符垂直排列，整体指向圆心，从扇区弧顶开始）
  drawVerticalText(ctx, text, x, y, isDimmed, radius, sliceAngle) {
    if (!text) return;
    
    // 根据扇区大小自适应调整字体大小
    const baseFontSize = 18; // 基础字体大小
    const minFontSize = 12; // 最小字体大小
    const arcLength = sliceAngle * radius; // 扇区弧长
    
    // 根据扇区弧长调整字体大小（根据用户偏好设置）
    let fontSize = baseFontSize;
    if (arcLength < 60) {
      // 扇区很小时，使用最小字体大小
      fontSize = minFontSize;
    } else if (arcLength < 100) {
      // 扇区较小时，按比例调整字体大小
      fontSize = minFontSize + (baseFontSize - minFontSize) * ((arcLength - 60) / 40);
    }
    // 弧长大于100时使用基础字体大小18px
    
    const lineHeight = fontSize; // 字符行高与字体大小一致
    
    // 提取表情符号和普通文字
    const emojis = this.extractEmojis(text);
    const textWithoutEmojis = this.removeEmojis(text);
    
    // 将文字拆分为单个字符（不包含表情符号）
    let chars = textWithoutEmojis.split('');
    
    // 计算扇区弧顶位置（从扇区起始角度对应的弧顶开始）
    // 扇区弧顶距离圆心的距离约为 radius - 一些边距
    const arcTopDistance = radius * 0.95; // 弧顶位置距离圆心的距离，更靠近边缘
    const startY = -arcTopDistance; // 从弧顶开始（负值表示向上）
    
    // 计算扇区弧长，确定可显示的字符数
    // 根据扇区大小动态调整可显示字符数比例
    // 扇区较小时使用更高的比例以显示更多字符
    let charDisplayRatio = 0.9; // 默认比例
    if (arcLength < 60) {
      // 扇区很小时，增加显示比例到95%
      charDisplayRatio = 0.95;
    } else if (arcLength < 100) {
      // 扇区较小时，使用90%的比例
      charDisplayRatio = 0.9;
    }
    
    // 进一步优化小扇区的字符显示数量
    // 当字体为最小字体时，增加可显示字符数
    let maxChars;
    if (fontSize === minFontSize) {
      // 当使用最小字体时，允许显示更多字符，使用更宽松的计算方式
      maxChars = Math.max(1, Math.min(chars.length, Math.floor((arcLength * charDisplayRatio) / (lineHeight * 0.8))));
    } else {
      maxChars = Math.max(1, Math.min(chars.length, Math.floor((arcLength * charDisplayRatio) / lineHeight)));
    }
    
    // 如果字符数为0，直接返回
    if (maxChars <= 0) return;
    
    // 计算字符间距，使文字在可用空间内居中分布
    // 使用动态计算的字符显示比例
    let spacing = Math.min(lineHeight, (arcLength * charDisplayRatio) / maxChars);
    
    // 当使用最小字体时，进一步减小字符间距以显示更多字符
    // if (fontSize === minFontSize) {
    //   spacing = spacing * 0.85; // 减小15%的间距
    // }
    
    // 设置字体大小
    ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
    
    // 限制显示的字符数
    maxChars = Math.min(maxChars, chars.length);
    
    // 逐个绘制字符（不包括表情符号）
    for (let i = 0; i < maxChars; i++) {
      // 字符位置从弧顶开始向圆心方向排列
      const charY = startY + i * spacing;
      
      // 保存当前上下文
      ctx.save();
      
      // 根据是否变暗调整透明度
      if (isDimmed) {
        ctx.globalAlpha = 0.5;
      }
      
      // 绘制描边
      ctx.strokeText(chars[i], x, charY);
      
      // 绘制填充文字
      ctx.fillText(chars[i], x, charY);
      
      // 恢复上下文
      ctx.restore();
    }
    
    // 如果有表情符号，在扇区末尾绘制它们
    if (emojis.length > 0) {
      // 计算表情符号的位置（在文字之后）
      const emojiY = startY + maxChars * spacing + 10; // 在文字下方10px处
      
      // 保存当前上下文
      ctx.save();
      
      // 根据是否变暗调整透明度
      if (isDimmed) {
        ctx.globalAlpha = 0.5;
      }
      
      // 设置表情符号的字体大小（稍大一些）
      const emojiFontSize = fontSize * 1.2;
      ctx.font = `${emojiFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      
      // 绘制表情符号
      ctx.fillText(emojis.join(' '), x, emojiY);
      
      // 恢复上下文
      ctx.restore();
    }
  },

  // 提取文本中的表情符号
  extractEmojis(text) {
    // 使用更全面的正则表达式匹配表情符号
    // 添加了U+1F900-U+1F9FF范围以支持芒果等表情符号
    // 添加了U+1FAD0-U+1FAD9范围以支持蓝莓和橄榄等表情符号
    // 进一步扩充范围以支持更多Unicode表情符号
    const emojiRegex = /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F700}-\u{1F77F}]|[\u{1F780}-\u{1F7FF}]|[\u{1F800}-\u{1F8FF}]|[\u{1F900}-\u{1F9FF}]|[\u{1FA00}-\u{1FA6F}]|[\u{1FA70}-\u{1FAFF}]|[\u{1FAD0}-\u{1FAD9}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu;
    const matches = text.match(emojiRegex);
    return matches || [];
  },

  // 移除文本中的表情符号
  removeEmojis(text) {
    // 使用更全面的正则表达式移除表情符号
    // 添加了U+1F900-U+1F9FF范围以支持芒果等表情符号
    // 添加了U+1FAD0-U+1FAD9范围以支持蓝莓和橄榄等表情符号
    // 进一步扩充范围以支持更多Unicode表情符号
    const emojiRegex = /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F700}-\u{1F77F}]|[\u{1F780}-\u{1F7FF}]|[\u{1F800}-\u{1F8FF}]|[\u{1F900}-\u{1F9FF}]|[\u{1FA00}-\u{1FA6F}]|[\u{1FA70}-\u{1FAFF}]|[\u{1FAD0}-\u{1FAD9}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu;
    return text.replace(emojiRegex, '').trim();
  },

  // 调整颜色亮度
  adjustColorBrightness(hex, percent) {
    // 将十六进制颜色转换为RGB
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);

    // 调整亮度
    const adjustedR = Math.min(255, Math.max(0, r + (r * percent / 100)));
    const adjustedG = Math.min(255, Math.max(0, g + (g * percent / 100)));
    const adjustedB = Math.min(255, Math.max(0, b + (b * percent / 100)));

    // 将调整后的RGB转换回十六进制
    return `#${adjustedR.toString(16).padStart(2, '0')}${adjustedG.toString(16).padStart(2, '0')}${adjustedB.toString(16).padStart(2, '0')}`;
  },

  // 绘制文字
  drawSectorText(ctx, centerX, centerY, radius, startAngle, sliceAngle, item, isDimmed, isHighlighted) {
    ctx.save();
    ctx.translate(centerX, centerY);
    const textAngle = startAngle + sliceAngle / 2 + Math.PI / 2;
    ctx.rotate(textAngle);
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';

    // 根据高亮状态设置文字样式
    if (isHighlighted) {
      // 高亮扇区的文字更加突出
      ctx.font = 'bold 22px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
      
      // 更强的文字描边
      ctx.strokeStyle = 'rgba(0, 0, 0, 0.9)';
      ctx.lineWidth = 2.5;
      // 修改为从弧顶开始的垂直文字排列
      this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
      
      // 高亮文字颜色
      ctx.fillStyle = '#ffffff';
      this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
      
      // 添加文字发光效果
      ctx.shadowColor = 'rgba(255, 255, 255, 1)';
      ctx.shadowBlur = 6;
      this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
      
    } else {
      // 普通文字样式
      ctx.font = 'bold 20px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
      
      // 文字描边
      ctx.strokeStyle = isDimmed ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.6)';
      ctx.lineWidth = 1.5;
      // 修改为从弧顶开始的垂直文字排列
      this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
      
      // 文字填充颜色
      ctx.fillStyle = isDimmed ? 'rgba(255, 255, 255, 0.5)' : '#ffffff';
      this.drawVerticalText(ctx, item.text, 0, 0, isDimmed, radius, sliceAngle);
    }
    
    // 清除阴影设置
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    
    ctx.restore();
  },

  // 绘制指针
  drawPointer(ctx, centerX, centerY, radius) {
    ctx.save();

    const pointerRadius = radius * 0.15;
    const pointerLength = radius * 0.25;
    
    ctx.translate(centerX, centerY);
    
    // 绘制指针主体（简洁的尖长三角形设计）
    // 指针主体渐变
    const pointerGradient = ctx.createLinearGradient(0, -pointerLength, 0, pointerRadius);
    pointerGradient.addColorStop(0, '#FFD700'); // 金色
    pointerGradient.addColorStop(0.5, '#FFA500'); // 橙色
    pointerGradient.addColorStop(1, '#FF8C00'); // 深橙色
    
    // 绘制指针三角形部分
    ctx.beginPath();
    ctx.moveTo(0, -pointerLength);
    ctx.lineTo(pointerRadius * 0.8, 0);
    ctx.lineTo(-pointerRadius * 0.8, 0);
    ctx.closePath();
    
    ctx.fillStyle = pointerGradient;
    ctx.fill();
    
    // 绘制指针边框（白色边框）
    ctx.strokeStyle = '#FFFFFF'; // 白色边框
    ctx.lineWidth = 1;
    ctx.lineJoin = 'round';
    ctx.stroke();
    
    // 绘制指针中心装饰圆
    const centerGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, pointerRadius * 0.7);
    centerGradient.addColorStop(0, '#FFFFFF');
    centerGradient.addColorStop(0.7, '#FFD700');
    centerGradient.addColorStop(1, '#FFA500');
    
    ctx.beginPath();
    ctx.arc(0, 0, pointerRadius * 0.75, 0, 2 * Math.PI);
    ctx.fillStyle = centerGradient;
    ctx.fill();
    
    ctx.strokeStyle = '#ffffff';
    ctx.lineWidth = 1;
    ctx.stroke();
    
    ctx.restore();
  },

  // 绘制中心按钮（带立体感的幸运星设计）
  drawCenterButton(ctx, centerX, centerY, radius) {
    const centerRadius = radius * 0.12;
    
    ctx.save();
    ctx.translate(centerX, centerY);
    
    // 绘制中心按钮的立体感背景
    const centerGradient = ctx.createRadialGradient(
      -centerRadius * 0.3, -centerRadius * 0.3, 0,
      0, 0, centerRadius * 1.2
    );
    centerGradient.addColorStop(0, 'rgba(255, 255, 255, 0.9)');
    centerGradient.addColorStop(0.7, 'rgba(255, 215, 0, 0.7)');
    centerGradient.addColorStop(1, 'rgba(255, 165, 0, 0.5)');
    
    ctx.beginPath();
    ctx.arc(0, 0, centerRadius, 0, 2 * Math.PI);
    ctx.fillStyle = centerGradient;
    ctx.fill();
    
    // 绘制中心按钮边框（白色边框）
    ctx.strokeStyle = '#FFFFFF';
    ctx.lineWidth = 1;
    ctx.stroke();
    
    // 绘制立体感的幸运星
    const starSize = centerRadius * 0.7;
    
    // 星星高光
    const starHighlight = ctx.createRadialGradient(
      -starSize * 0.2, -starSize * 0.2, 0,
      0, 0, starSize
    );
    starHighlight.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
    starHighlight.addColorStop(0.5, 'rgba(255, 215, 0, 0.6)');
    starHighlight.addColorStop(1, 'rgba(255, 165, 0, 0.4)');
    
    ctx.fillStyle = starHighlight;
    
    // 绘制五角星
    ctx.beginPath();
    for (let i = 0; i < 5; i++) {
      const angle = (i * 4 * Math.PI) / 5 - Math.PI / 2;
      const x = Math.cos(angle) * starSize;
      const y = Math.sin(angle) * starSize;
      if (i === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }
      
      const innerAngle = ((i * 2 + 1) * Math.PI) / 5 - Math.PI / 2;
      const innerX = Math.cos(innerAngle) * starSize * 0.5;
      const innerY = Math.sin(innerAngle) * starSize * 0.5;
      ctx.lineTo(innerX, innerY);
    }
    ctx.closePath();
    ctx.fill();
    
    // 星星边框
    ctx.strokeStyle = 'rgba(184, 134, 11, 0.9)';
    ctx.lineWidth = 1.5;
    ctx.lineJoin = 'round';
    ctx.stroke();
    
    ctx.restore();
  },

  // 绘制粒子效果
  drawParticles(ctx, centerX, centerY, radius) {
    const { particles } = this.data;
    
    // 检查设备信息以确定兼容性处理方式
    let isHighPerformanceDevice = true;
    try {
      const systemInfo = wx.getSystemInfoSync();
      const isIOS = systemInfo.platform === 'ios';
      const isAndroid = systemInfo.platform === 'android';
      const isMobile = isIOS || isAndroid;
      
      // 在移动设备上使用简化版本以提高兼容性
      isHighPerformanceDevice = !isMobile || (isAndroid && systemInfo.system && parseFloat(systemInfo.system) >= 10);
    } catch (e) {
      logError('获取系统信息失败，使用默认设置', e);
    }
    
    particles.forEach(particle => {
      // 绘制轨迹尾光
      for (let i = 0; i < particle.trail.length - 1; i++) {
        const point = particle.trail[i];
        const nextPoint = particle.trail[i + 1];
        
        // 添加有效性检查
        if (!point || !nextPoint) continue;
        
        // 确保alpha值在有效范围内
        const pointAlpha = Math.max(0, Math.min(1, point.alpha || 0));
        const nextPointAlpha = Math.max(0, Math.min(1, nextPoint.alpha || 0));
        
        if (pointAlpha > 0.01 && nextPointAlpha > 0.01) {
          ctx.save();
          ctx.globalAlpha = pointAlpha;
          
          // 检查坐标是否有效
          if (isNaN(point.x) || isNaN(point.y) || isNaN(nextPoint.x) || isNaN(nextPoint.y)) {
            ctx.restore();
            continue;
          }
          
          // 创建尾光效果（改进兼容性）
          try {
            // 使用更兼容的颜色处理方式
            const hue = Math.max(0, Math.min(360, (particle.hue + i * 10) % 360));
            
            if (isHighPerformanceDevice) {
              // 高性能设备保留渐变效果
              const gradient = ctx.createLinearGradient(
                point.x, point.y,
                nextPoint.x, nextPoint.y
              );
              
              // 添加颜色停止点
              const color1 = this.hslToRgbString(hue, 100, 70, pointAlpha);
              const color2 = this.hslToRgbString((hue + 30) % 360, 100, 50, nextPointAlpha * 0.5);
              
              gradient.addColorStop(0, color1);
              gradient.addColorStop(1, color2);
              
              ctx.strokeStyle = gradient;
            } else {
              // 低性能设备或移动设备使用固定颜色
              const rgbColor = this.hslToRgb(hue, 100, 70);
              ctx.strokeStyle = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${(pointAlpha + nextPointAlpha) / 2})`;
            }
            
            ctx.lineWidth = Math.max(0, particle.size * (i / particle.trail.length) * 2);
            ctx.lineCap = 'round';
            ctx.lineJoin = 'round';
            
            ctx.beginPath();
            ctx.moveTo(point.x, point.y);
            ctx.lineTo(nextPoint.x, nextPoint.y);
            ctx.stroke();
          } catch (e) {
            // 如果渐变创建失败，使用简单颜色
            ctx.strokeStyle = `rgba(255, 255, 255, ${(pointAlpha + nextPointAlpha) / 2})`;
            ctx.lineWidth = Math.max(0, particle.size * (i / particle.trail.length) * 2);
            ctx.lineCap = 'round';
            ctx.lineJoin = 'round';
            
            ctx.beginPath();
            ctx.moveTo(point.x, point.y);
            ctx.lineTo(nextPoint.x, nextPoint.y);
            ctx.stroke();
          }
          
          ctx.restore();
        }
      }
      
      // 绘制主粒子
      ctx.save();
      
      // 确保alpha值在有效范围内
      const particleAlpha = Math.max(0, Math.min(1, particle.alpha || 0));
      ctx.globalAlpha = particleAlpha;
      
      // 检查坐标是否有效
      if (isNaN(particle.x) || isNaN(particle.y) || isNaN(particle.size)) {
        ctx.restore();
        return;
      }
      
      // 创建粒子效果（改进兼容性）
      try {
        const hue = Math.max(0, Math.min(360, particle.hue || 0));
        
        if (isHighPerformanceDevice) {
          // 高性能设备保留径向渐变效果
          const gradient = ctx.createRadialGradient(
            particle.x, particle.y, 0,
            particle.x, particle.y, Math.max(0, particle.size)
          );
          
          const color1 = this.hslToRgbString(hue, 100, 100, particleAlpha);
          const color2 = this.hslToRgbString((hue + 10) % 360, 100, 70, Math.max(0, Math.min(1, particleAlpha * 0.8)));
          const color3 = this.hslToRgbString((hue + 20) % 360, 100, 50, 0);
          
          gradient.addColorStop(0, color1);
          gradient.addColorStop(0.5, color2);
          gradient.addColorStop(1, color3);
          
          ctx.fillStyle = gradient;
        } else {
          // 低性能设备或移动设备使用纯色
          const rgbColor = this.hslToRgb(hue, 100, 80);
          ctx.fillStyle = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${particleAlpha})`;
        }
      } catch (e) {
        // 如果渐变创建失败，使用简单颜色
        ctx.fillStyle = `rgba(255, 255, 255, ${particleAlpha})`;
      }
      
      ctx.beginPath();
      ctx.arc(particle.x, particle.y, Math.max(0, particle.size), 0, 2 * Math.PI);
      ctx.fill();
      
      ctx.restore();
    });
  },

  // HSL转RGB颜色值
  hslToRgb(h, s, l) {
    h /= 360;
    s /= 100;
    l /= 100;
    
    let r, g, b;
    
    if (s === 0) {
      r = g = b = l; // achromatic
    } else {
      const hue2rgb = (p, q, t) => {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1/6) return p + (q - p) * 6 * t;
        if (t < 1/2) return q;
        if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
        return p;
      };
      
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      r = hue2rgb(p, q, h + 1/3);
      g = hue2rgb(p, q, h);
      b = hue2rgb(p, q, h - 1/3);
    }
    
    return {
      r: Math.round(r * 255),
      g: Math.round(g * 255),
      b: Math.round(b * 255)
    };
  },

  // HSL转RGBA字符串
  hslToRgbString(h, s, l, a) {
    const rgb = this.hslToRgb(h, s, l);
    return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a})`;
  },

  // 初始化粒子系统
  initParticles(centerX, centerY, radius) {
    const particles = [];
    const particleCount = 20; // 增加粒子数量以获得更好的流光效果
    
    for (let i = 0; i < particleCount; i++) {
      const angle = (i / particleCount) * 2 * Math.PI;
      const distance = radius * 0.8 + Math.random() * radius * 0.2;
      
      // 为流光粒子添加轨迹点数组
      const trail = [];
      for (let j = 0; j < 5; j++) { // 每个粒子保留5个轨迹点
        trail.push({
          x: centerX + Math.cos(angle) * distance,
          y: centerY + Math.sin(angle) * distance,
          alpha: 0
        });
      }
      
      particles.push({
        x: centerX + Math.cos(angle) * distance,
        y: centerY + Math.sin(angle) * distance,
        size: 2 + Math.random() * 3,
        alpha: 0.8 + Math.random() * 0.2,
        angle: angle,
        distance: distance,
        speed: 0.02 + Math.random() * 0.03,
        trail: trail, // 轨迹点数组
        hue: Math.random() * 360 // 随机色相，用于彩色流光效果
      });
    }
    
    this.setData({ particles });
  },

  // 更新粒子位置
  updateParticles(centerX, centerY, rotation) {
    const { particles } = this.data;
    
    particles.forEach(particle => {
      // 更新轨迹点
      particle.trail.push({
        x: particle.x,
        y: particle.y,
        alpha: particle.alpha
      });
      
      // 保持轨迹点数量为5个
      if (particle.trail.length > 5) {
        particle.trail.shift();
      }
      
      // 根据转盘旋转更新粒子位置
      const currentAngle = particle.angle + rotation * 0.5; // 粒子跟随转盘但速度略慢
      particle.x = centerX + Math.cos(currentAngle) * particle.distance;
      particle.y = centerY + Math.sin(currentAngle) * particle.distance;
      
      // 粒子闪烁效果
      particle.alpha = 0.3 + 0.5 * (1 + Math.sin(Date.now() * particle.speed + particle.angle * 10));
      
      // 更新轨迹点的透明度，创建尾光效果
      for (let i = 0; i < particle.trail.length; i++) {
        const trailPoint = particle.trail[i];
        trailPoint.alpha = particle.alpha * (i / particle.trail.length) * 0.5; // 尾光透明度递减
      }
    });
    
    this.setData({ particles });
  },

  // 16进制颜色转 RGB
  hexToRgb(hex) {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : { r: 0, g: 0, b: 0 };
  },

  // 增亮颜色函数
  brightenColor(rgb, factor) {
    return {
      r: Math.min(255, Math.round(rgb.r * factor)),
      g: Math.min(255, Math.round(rgb.g * factor)),
      b: Math.min(255, Math.round(rgb.b * factor))
    };
  },

// 旋转转盘（支持粒子效果和结果突出）
  spinWheel() {
    if (this.data.spinning || this.data.currentMode !== 'wheel') return;

    const rotationDuration = app.globalData.spinDuration * 1000;
    const vibrateInterval = 200;
    
    // 重置结果突出显示
    this.setData({ resultSectorIndex: -1 });
    
    // 初始化粒子系统
    const { canvasWidth, canvasHeight } = this.data;
    const centerX = canvasWidth / 2;
    const centerY = canvasHeight / 2;
    const radius = Math.min(centerX, centerY) - 4;
    
    this.initParticles(centerX, centerY, radius);
    this.setData({ showParticles: true });
    
    // 振动判断：若全局振动开关开启
    if (app.globalData.vibrateEnabled) {
      const startTime = Date.now();
      const vibrateTimer = setInterval(() => {
        if (Date.now() - startTime >= rotationDuration) {
          clearInterval(vibrateTimer);
          return;
        }
        wx.vibrateShort({
          fail: (err) => {
            logInfo('振动调用失败：', err);
            clearInterval(vibrateTimer);
          }
        });
      }, vibrateInterval);
      
      setTimeout(() => {
        clearInterval(vibrateTimer);
      }, rotationDuration);
    }

    this.setData({ spinning: true, result: '???' });

    const { wheelItems, rotation: currentRotation = 0 } = this.data;
    const totalWeight = wheelItems.reduce((sum, item) => sum + item.weight, 0);
    const totalRadians = 2 * Math.PI;
    const randomCircles = 2 + Math.random() * 2;
    // const randomCircles = 0.5; // 调试代码
    const baseRotation = randomCircles * totalRadians;
    const sectorAngles = wheelItems.map(item => (item.weight / totalWeight) * totalRadians);
    const targetAngle = currentRotation + baseRotation;
    
    // 计算最终结果扇区（用于确定减速过程中的显示顺序）
    let normalizedAngle = targetAngle % totalRadians;
    if (normalizedAngle < 0) {
      normalizedAngle += totalRadians;
    }
    
    const pointerAngle = totalRadians - normalizedAngle;
    let accumulatedAngle = 0;
    let finalSectorIndex = 0;
    for (let i = 0; i < wheelItems.length; i++) {
      accumulatedAngle += sectorAngles[i];
      if (pointerAngle < accumulatedAngle) {
        finalSectorIndex = i;
        break;
      }
    }
    
    // 保存最终结果扇区索引，用于实时结果显示逻辑
    this.setData({ finalSectorIndex });
    
    // 执行旋转动画
    this.animateWheel(targetAngle, () => {
      // 停止粒子效果
      this.setData({ showParticles: false });
      
      // 播放提示音
      const { audioCtx, soundEnabled } = this.data;
      if (soundEnabled && audioCtx) {
        audioCtx.seek(0);
        audioCtx.offError();
        audioCtx.offPlay();
        audioCtx.onError((err) => {
          logInfo('提示音播放失败：', err);
          wx.showToast({
            title: '提示音播放失败',
            icon: 'none',
            duration: 800
          });
        });
        audioCtx.onPlay(() => {
          logInfo('提示音播放成功');
        });
        audioCtx.play();
      }
      
      // 记录历史记录
      const recordHistory = () => {
        try {
          const { wheelName } = this.data;
          const result = wheelItems[finalSectorIndex].text;
          const currentWheel = app.globalData.currentWheel;
          
          // 保存工具历史记录（用于个人中心展示）
          this.saveGameHistory('wheel', `${wheelName}`, result);
          
          // 保存转盘专用历史记录（用于统计信息）
          if (currentWheel && currentWheel.id) {
            this.saveWheelHistory(currentWheel.id, wheelName, result);
          }
        } catch (e) {
          logError('保存历史记录失败', e);
        }
      };

      recordHistory();
      
      // 设置结果和突出显示
      this.setData({ 
        spinning: false,
        rotation: targetAngle,
        result: wheelItems[finalSectorIndex].text,
        resultSectorIndex: finalSectorIndex, // 设置结果扇区索引用于突出显示
        finalSectorIndex: -1 // 重置最终扇区索引
      });
      
      // 调用转盘奖励
      this.addSpinReward();
      
      // 重新绘制转盘以显示结果突出效果
      this.drawWheel(targetAngle);
    });
  },

  // 动画旋转（支持粒子效果和实时结果显示）
  animateWheel(targetAngle, callback) {
    const duration = app.globalData.spinDuration * 1000;
    const startTime = Date.now();
    const startRotation = this.data.rotation || 0;
    
    // 获取粒子效果所需的参数
    const { canvasWidth, canvasHeight } = this.data;
    const centerX = canvasWidth / 2;
    const centerY = canvasHeight / 2;
    
    const animate = () => {
      const currentTime = Date.now();
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);
      
      // 使用缓动函数使旋转更自然
      const easing = 1 - Math.pow(1 - progress, 3);
      const rotation = startRotation + (targetAngle - startRotation) * easing;
      
      // 更新粒子位置（如果开启了粒子效果）
      if (this.data.showParticles) {
        this.updateParticles(centerX, centerY, rotation);
      }
      
      // 实时计算并显示12点钟方向指向的扇区内容
      this.updateRealTimeResult(rotation, progress);
      
      this.drawWheel(rotation);
      
      if (progress < 1) {
        this.animationFrame = setTimeout(animate, 16);
      } else {
        this.setData({ rotation });
        callback && callback();
      }
    };
    
    animate();
  },

  // 实时更新12点钟方向指向的扇区内容
  updateRealTimeResult(rotation, progress) {
    const { wheelItems, finalSectorIndex } = this.data;
    if (!wheelItems || wheelItems.length === 0) return;
    
    const totalWeight = wheelItems.reduce((sum, item) => sum + item.weight, 0);
    const totalRadians = 2 * Math.PI;
    const sectorAngles = wheelItems.map(item => (item.weight / totalWeight) * totalRadians);
    
    // 更新实时结果显示（只在旋转过程中更新）
    if (this.data.spinning) {
      // 计算12点钟方向对应的扇区（以扇区右侧边框为准）
      // 根据规范，转盘旋转停止时，应以扇区右侧边框对准12点钟方向作为最终结果判定位置
      let normalizedAngle = (rotation) % totalRadians;
      if (normalizedAngle < 0) {
        normalizedAngle += totalRadians;
      }
      
      // 计算当前指向的扇区（使用平滑过渡算法）
      let accumulatedAngle = 0;
      let currentSectorIndex = 0;
      
      // 为了使结果显示更加平缓，我们添加一个过渡区域判断
      // 当指针接近扇区边界时，保持当前结果不变，避免频繁切换
      const transitionThreshold = 0.1; // 过渡阈值，弧度单位
      
      for (let i = wheelItems.length - 1; i >= 0 ; i--) {
        const nextAccumulatedAngle = accumulatedAngle + sectorAngles[i];
        
        // 检查是否在当前扇区范围内
        if (normalizedAngle >= accumulatedAngle && normalizedAngle < nextAccumulatedAngle) {
          currentSectorIndex = i;
          
          // 检查是否接近扇区边界，如果是则保持当前结果不变
          const distanceToStart = normalizedAngle - accumulatedAngle;
          const distanceToEnd = nextAccumulatedAngle - normalizedAngle;
          
          // 如果接近边界，则不更新结果，保持平缓过渡
          if (distanceToStart < transitionThreshold || distanceToEnd < transitionThreshold) {
            // 保持当前结果不变
            return;
          }
          
          break;
        }
        accumulatedAngle = nextAccumulatedAngle;
      }
      
      // 平滑更新结果，避免突然变化
      const currentResult = this.data.result;
      const newResult = wheelItems[currentSectorIndex].text;
      
      // 只有当结果真正改变时才更新，进一步减少不必要的更新
      if (currentResult !== newResult) {
        this.setData({ 
          result: newResult 
        });
      }
    }
  },

  onCanvasTouch(e) {
    // 处理触摸事件，可以扩展为手势旋转等功能
  },

  onUnload() {
    // 清除动画帧
    if (this.animationFrame) {
      clearTimeout(this.animationFrame);
    }
    if (this.coinAnimationFrame) {
      clearTimeout(this.coinAnimationFrame);
    }

    
    // 清除背景动画定时器
    if (this.data.backgroundAnimationTimer) {
      clearTimeout(this.data.backgroundAnimationTimer);
    }
    
    // 停止背景动画
    this.setData({
      backgroundAnimationActive: false
    });
    
    // 销毁音频上下文，防止内存泄漏
    if (this.data.audioCtx) {
      this.data.audioCtx.destroy();
    }
    if (this.data.muyuAudioCtx) {
      this.data.muyuAudioCtx.destroy();
    }
    if (this.data.coinAudioCtx) {
      this.data.coinAudioCtx.destroy();
    }
    if (this.data.cardsAudioCtx) {
      this.data.cardsAudioCtx.destroy();
    }
    if (this.data.fortuneAudioCtx) {
      this.data.fortuneAudioCtx.destroy();
    }
  },

  // 转盘奖励方法
  addSpinReward() {
    const today = this.getToday();
    const hasSpinToday = wx.getStorageSync('hasSpinToday') || false;
    
    if (!hasSpinToday) {
      // 今日首次转动转盘
      this.addLuckyExp(1); // 修改数值调试等级
      wx.setStorageSync('hasSpinToday', true);
      
      wx.showToast({
        title: '首次转盘+1经验',
        icon: 'success',
        duration: 1000
      });
    }
  },

  // 增加幸运经验
  addLuckyExp(exp) {
    let luckyLevel = wx.getStorageSync('luckyLevel') || 0;
    let luckyExp = wx.getStorageSync('luckyExp') || 0;
    const levelExpRequirements = [10, 50, 100, 500, 1000, 2000, 5000, 10000]; // LV0-LV7升级所需经验
    
    luckyExp += exp;
    
    // 检查是否升级
    while (luckyLevel < 8 && luckyExp >= levelExpRequirements[luckyLevel]) {
      luckyExp -= levelExpRequirements[luckyLevel];
      luckyLevel += 1;
      wx.showToast({
        title: `恭喜升级到LV${luckyLevel}!`,
        icon: 'success',
        duration: 1000
      });
    }
    
    wx.setStorageSync('luckyLevel', luckyLevel);
    wx.setStorageSync('luckyExp', luckyExp);
  },

  // 获取今天日期字符串
  getToday() {
    const now = new Date();
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
  },

  // 加载每日模式使用状态
  loadDailyModeStatus() {
    try {
      const hasCoinToday = wx.getStorageSync('hasCoinToday') || false;
      const hasCardsToday = wx.getStorageSync('hasCardsToday') || false;
      const hasMuyuToday = wx.getStorageSync('hasMuyuToday') || false;
      const hasFortuneToday = wx.getStorageSync('hasFortuneToday') || false;
      
      this.setData({
        hasCoinToday,
        hasCardsToday,
        hasMuyuToday,
        hasFortuneToday
      });
    } catch (e) {
      logError('加载每日模式状态失败', e);
    }
  },

  // 通用每日首次奖励方法
  addModeReward(mode, modeName, storageKey) {
    const todayUsed = wx.getStorageSync(storageKey) || false;
    
    if (!todayUsed) {
      // 今日首次使用该模式
      this.addLuckyExp(1);
      wx.setStorageSync(storageKey, true);
      
      // 更新页面状态
      const updateData = {};
      updateData[storageKey] = true;
      this.setData(updateData);
      
      // 延迟显示提示，避免与其他提示冲突
      setTimeout(() => {
        wx.showToast({
          title: `首次${modeName}+1经验`,
          icon: 'success',
          duration: 1000
        });
      }, 500);
    }
  },

  // 初始化提示音上下文（需提前准备 "ding.mp3" 音频文件）
  initAudioContext() {
    // 创建音频上下文
    const audioCtx = wx.createInnerAudioContext();
    // 设置音频源（需将 "ding.mp3" 放在项目根目录的 "audio" 文件夹下）
    audioCtx.src = '/audio/ding.mp3';
    // 配置音频播放参数（循环关闭、自动播放关闭）
    audioCtx.loop = false;
    audioCtx.autoplay = false;
    
    // 保存到数据中，供后续调用
    this.setData({ audioCtx });
  },

  // 初始化木鱼敲击音效上下文
  initMuyuAudioContext() {
    logInfo('开始初始化木鱼音效上下文...');
    
    try {
      // 创建木鱼音效上下文
      const muyuAudioCtx = wx.createInnerAudioContext();
      
      // 设置木鱼音效源
      muyuAudioCtx.src = '/audio/muyu-sound.mp3';
      
      // 配置音频播放参数
      muyuAudioCtx.loop = false;
      muyuAudioCtx.autoplay = false;
      muyuAudioCtx.volume = 1.0; // 设置音量
      
      logInfo('木鱼音效源设置为:', muyuAudioCtx.src);
      
      // 只在初始化时绑定一次事件监听器
      muyuAudioCtx.onCanplay(() => {
        // logInfo('木鱼音效加载完成，可以播放');
      });
      
      muyuAudioCtx.onWaiting(() => {
        // logInfo('木鱼音效正在缓冲...');
      });
      
      muyuAudioCtx.onPlay(() => {
        // logInfo('木鱼音效开始播放');
      });
      
      muyuAudioCtx.onEnded(() => {
        // logInfo('木鱼音效播放结束');
      });
      
      muyuAudioCtx.onError((err) => {
        logError('木鱼音效播放错误:', err);
        logError('错误码:', err.errCode);
        logError('错误信息:', err.errMsg);
        
        // 显示错误提示（仅调试时显示）
        if (typeof __wxConfig !== 'undefined' && __wxConfig.debug) {
          wx.showToast({
            title: `木鱼音效错误: ${err.errMsg}`,
            icon: 'none',
            duration: 1000
          });
        }
      });
      
      // 保存到数据中
      this.setData({ muyuAudioCtx });
      
      logInfo('木鱼音效上下文初始化完成');
      
    } catch (error) {
      logError('初始化木鱼音效上下文异常:', error);
    }
  },

  // 初始化抛硬币音效上下文
  initCoinAudioContext() {
    logInfo('开始初始化抛硬币音效上下文...');
    
    try {
      // 创建抛硬币音效上下文
      const coinAudioCtx = wx.createInnerAudioContext();
      
      // 设置抛硬币音效源
      coinAudioCtx.src = '/audio/paoyingbi.mp3';
      
      // 配置音频播放参数
      coinAudioCtx.loop = false;
      coinAudioCtx.autoplay = false;
      coinAudioCtx.volume = 1.0; // 设置音量
      
      logInfo('抛硬币音效源设置为:', coinAudioCtx.src);
      
      // 添加加载成功回调
      coinAudioCtx.onCanplay(() => {
        // logInfo('抛硬币音效加载完成，可以播放');
      });
      
      // 添加等待数据回调
      coinAudioCtx.onWaiting(() => {
        // logInfo('抛硬币音效正在缓冲...');
      });
      
      // 添加错误处理
      coinAudioCtx.onError((err) => {
        logError('抛硬币音效初始化或加载失败:', err);
        logError('错误码:', err.errCode);
        logError('错误信息:', err.errMsg);
        
        // 显示错误提示（仅调试时显示）
        if (typeof __wxConfig !== 'undefined' && __wxConfig.debug) {
          wx.showToast({
            title: `抛硬币音效加载失败: ${err.errMsg}`,
            icon: 'none',
            duration: 1000
          });
        }
      });
      
      // 保存到数据中
      this.setData({ coinAudioCtx });
      
      logInfo('抛硬币音效上下文初始化完成');
      
    } catch (error) {
      logError('初始化抛硬币音效上下文异常:', error);
    }
  },

  // 初始化翻牌子音效上下文
  initCardsAudioContext() {
    logInfo('开始初始化翻牌子音效上下文...');
    
    try {
      // 创建翻牌子音效上下文
      const cardsAudioCtx = wx.createInnerAudioContext();
      
      // 设置翻牌子音效源
      cardsAudioCtx.src = '/audio/fanpaizi.mp3';
      
      // 配置音频播放参数
      cardsAudioCtx.loop = false;
      cardsAudioCtx.autoplay = false;
      cardsAudioCtx.volume = 1.0; // 设置音量
      
      logInfo('翻牌子音效源设置为:', cardsAudioCtx.src);
      
      // 添加加载成功回调
      cardsAudioCtx.onCanplay(() => {
        // logInfo('翻牌子音效加载完成，可以播放');
      });
      
      // 添加等待数据回调
      cardsAudioCtx.onWaiting(() => {
        // logInfo('翻牌子音效正在缓冲...');
      });
      
      // 添加错误处理
      cardsAudioCtx.onError((err) => {
        logError('翻牌子音效初始化或加载失败:', err);
        logError('错误码:', err.errCode);
        logError('错误信息:', err.errMsg);
        
        // 显示错误提示（仅调试时显示）
        if (typeof __wxConfig !== 'undefined' && __wxConfig.debug) {
          wx.showToast({
            title: `翻牌子音效加载失败: ${err.errMsg}`,
            icon: 'none',
            duration: 1000
          });
        }
      });
      
      // 保存到数据中
      this.setData({ cardsAudioCtx });
      
      logInfo('翻牌子音效上下文初始化完成');
      
    } catch (error) {
      logError('初始化翻牌子音效上下文异常:', error);
    }
  },

  // 初始化洗牌音效上下文
  initShuffleAudioContext() {
    logInfo('开始初始化洗牌音效上下文...');
    
    try {
      // 创建洗牌音效上下文
      const shuffleAudioCtx = wx.createInnerAudioContext();
      
      // 设置洗牌音效源
      shuffleAudioCtx.src = '/audio/xipai.mp3';
      
      // 配置音频播放参数
      shuffleAudioCtx.loop = false;
      shuffleAudioCtx.autoplay = false;
      shuffleAudioCtx.volume = 1.0; // 设置音量
      
      logInfo('洗牌音效源设置为:', shuffleAudioCtx.src);
      
      // 添加加载成功回调
      shuffleAudioCtx.onCanplay(() => {
        // logInfo('洗牌音效加载完成，可以播放');
      });
      
      // 添加等待数据回调
      shuffleAudioCtx.onWaiting(() => {
        // logInfo('洗牌音效正在缓冲...');
      });
      
      // 添加错误处理
      shuffleAudioCtx.onError((err) => {
        logError('洗牌音效初始化或加载失败:', err);
        logError('错误码:', err.errCode);
        logError('错误信息:', err.errMsg);
        
        // 显示错误提示（仅调试时显示）
        if (typeof __wxConfig !== 'undefined' && __wxConfig.debug) {
          wx.showToast({
            title: `洗牌音效加载失败: ${err.errMsg}`,
            icon: 'none',
            duration: 1000
          });
        }
      });
      
      // 保存到数据中
      this.setData({ shuffleAudioCtx });
      
      logInfo('洗牌音效上下文初始化完成');
      
    } catch (error) {
      logError('初始化洗牌音效上下文异常:', error);
    }
  },

  // 初始化幸运抽签音效上下文
  initFortuneAudioContext() {
    logInfo('开始初始化幸运抽签音效上下文...');
    
    try {
      // 创建幸运抽签音效上下文
      const fortuneAudioCtx = wx.createInnerAudioContext();
      
      // 设置幸运抽签音效源
      fortuneAudioCtx.src = '/audio/chouqian.mp3';
      
      // 配置音频播放参数
      fortuneAudioCtx.loop = false;
      fortuneAudioCtx.autoplay = false;
      fortuneAudioCtx.volume = 1.0; // 设置音量
      
      logInfo('幸运抽签音效源设置为:', fortuneAudioCtx.src);
      
      // 添加加载成功回调
      fortuneAudioCtx.onCanplay(() => {
        // logInfo('幸运抽签音效加载完成，可以播放');
      });
      
      // 添加等待数据回调
      fortuneAudioCtx.onWaiting(() => {
        // logInfo('幸运抽签音效正在缓冲...');
      });
      
      // 添加错误处理
      fortuneAudioCtx.onError((err) => {
        logError('幸运抽签音效初始化或加载失败:', err);
        logError('错误码:', err.errCode);
        logError('错误信息:', err.errMsg);
        
        // 显示错误提示（仅调试时显示）
        if (typeof __wxConfig !== 'undefined' && __wxConfig.debug) {
          wx.showToast({
            title: `幸运抽签音效加载失败: ${err.errMsg}`,
            icon: 'none',
            duration: 1000
          });
        }
      });
      
      // 保存到数据中
      this.setData({ fortuneAudioCtx });
      
      logInfo('幸运抽签音效上下文初始化完成');
      
    } catch (error) {
      logError('初始化幸运抽签音效上下文异常:', error);
    }
  },

  // 切换设置菜单显示状态
  toggleSettingsMenu() {
    this.setData({
      showSettingsMenu: !this.data.showSettingsMenu
    });
  },
  

  // 设置旋转时长
  setSpinDuration() {
    wx.showModal({
      title: '设置旋转时长(秒)',
      content: '',
      editable: true,
      // placeholderText: this.data.spinDuration.toString(),
      placeholderText: "限制1-10",
      success: (res) => {
        if (res.confirm) {
          const duration = parseInt(res.content) || 5;
          const validDuration = Math.max(1, Math.min(10, duration)); // 限制在1-10秒之间
          
          this.setData({ spinDuration: validDuration });
          
          const app = getApp();
          app.globalData.spinDuration = validDuration;
          
          wx.showToast({
            title: '设置成功',
            icon: 'success'
          });
        }
      }
    });
  },
  

  // 处理振动开关变更
  onVibrateChange(e) {
    const enabled = e.detail.value;
    this.setData({ vibrateEnabled: enabled });
    app.globalData.vibrateEnabled = enabled;
  },
  

  // 处理声音开关变更
  onSoundChange(e) {
    const enabled = e.detail.value;
    this.setData({ soundEnabled: enabled });
    app.globalData.soundEnabled = enabled;
  },
  

  // 处理修改按钮点击
  onEditClick() {
    // 这里可以跳转到编辑页面或显示编辑弹窗
    // 示例：wx.navigateTo({ url: '/pages/edit-wheel/edit-wheel' })
    wx.showToast({
      title: '编辑功能待实现',
      icon: 'none'
    });
  },

  // 点击分享按钮显示菜单
  onShareClick() {
    // 显示分享菜单
    wx.showShareMenu({
      withShareTicket: true,
      menus: ['shareAppMessage', 'shareTimeline']
    })
  },
  
  // 配置分享给好友
  onShareAppMessage() {
    logInfo('分享功能触发');
    const { currentMode, wheelName, modeNames, currentModeIndex } = this.data;
    
    let shareTitle = '';
    let sharePath = '/pages/index/index';
    
    if (currentMode === 'wheel') {
      // 转盘模式：分享当前转盘
      shareTitle = `来帮我决定${wheelName}吧！`;
      sharePath = '/pages/index/index';
    } else {
      // 其他模式：分享对应的模式
      const modeName = modeNames[currentModeIndex] || '小幸运转盘';
      shareTitle = `一起来${modeName}吧！`;
      sharePath = `/pages/index/index?mode=${currentModeIndex}`;
    }
    
    logInfo('分享内容:', { title: shareTitle, path: sharePath });
    
    return {
      title: shareTitle,
      path: sharePath, // 分享后打开的页面路径
      imageUrl: '', // 可选，分享时显示的图片
      success: (res) => {
        logInfo('分享成功', res);
        wx.showToast({
          title: '分享成功',
          icon: 'success',
          duration: 1000
        });
      },
      fail: (res) => {
        logInfo('分享失败', res);
        wx.showToast({
          title: '分享失败',
          icon: 'none',
          duration: 1000
        });
      }
    }
  },
  
  // 配置分享到朋友圈
  onShareTimeline() {
    const { currentMode, wheelName, modeNames, currentModeIndex } = this.data;
    
    let shareTitle = '';
    let shareQuery = 'page=index';
    
    if (currentMode === 'wheel') {
      // 转盘模式：分享当前转盘
      shareTitle = `来帮我决定${wheelName}吧！`;
      shareQuery = 'page=index';
    } else {
      // 其他模式：分享对应的模式
      const modeName = modeNames[currentModeIndex] || '小幸运转盘';
      shareTitle = `一起来${modeName}吧！`;
      shareQuery = `page=index&mode=${currentModeIndex}`;
    }
    
    return {
      title: shareTitle,
      query: shareQuery, // 分享携带的参数
      imageUrl: '', // 可选，分享时显示的图片
    }
  },

  // 向左切换模式（直接切换并重绘画面）
  switchToLeftMode() {
    let newIndex = this.data.currentModeIndex - 1;
    if (newIndex < 0) {
      newIndex = this.data.modes.length - 1; // 循环到最后一个
    }
    
    // 直接切换模式并重绘画面
    this.switchToMode(newIndex);
  },

  // 向右切换模式（直接切换并重绘画面）
  switchToRightMode() {
    let newIndex = this.data.currentModeIndex + 1;
    if (newIndex >= this.data.modes.length) {
      newIndex = 0; // 循环到第一个
    }
    
    // 直接切换模式并重绘画面
    this.switchToMode(newIndex);
  },

  // 中间模式按钮点击事件处理（根据当前模式执行对应功能）
  onModeButtonTap() {
    const { currentMode, resultSectorIndex } = this.data;
    
    switch (currentMode) {
      case 'wheel':
        // 转盘模式：根据转盘状态执行不同功能
        if (resultSectorIndex === -1) {
          // 转盘为初始状态，执行旋转转盘功能
          this.spinWheel();
        } else {
          // 转盘不为初始状态，执行重置转盘功能
          this.redrawWheel();
        }
        break;
      case 'coin':
        // 抛硬币模式：执行抛硬币功能
        this.flipCoin();
        break;

      case 'cards':
        // 翻牌子模式：执行重置牌子功能并播放洗牌音效
        this.playShuffleSound();
        this.resetCards();
        break;
      case 'muyu':
        // 减压敲模式：执行敲击木鱼功能
        this.performKnockAnimation();
        break;
      case 'fortune':
        // 幸运抽签模式：执行开始抽签功能
        this.onFortuneStart();
        break;
      default:
        logInfo('未知模式:', currentMode);
        break;
    }
  },

  // 播放洗牌音效
  playShuffleSound() {
    const { shuffleAudioCtx, soundEnabled } = this.data;
    
    // 检查全局声音开关和音效上下文是否存在
    if (!soundEnabled || !shuffleAudioCtx) {
      logInfo('洗牌音效未播放：', { soundEnabled, hasAudioCtx: !!shuffleAudioCtx });
      return;
    }
    
    try {
      // 重新设置播放位置到开始，以便可以重复播放
      shuffleAudioCtx.seek(0);
      
      // 添加播放成功回调
      shuffleAudioCtx.onPlay(() => {
        logInfo('洗牌音效播放成功！');
      });
      
      // 添加播放结束回调
      shuffleAudioCtx.onEnded(() => {
        logInfo('洗牌音效播放结束');
      });
      
      // 添加错误回调
      shuffleAudioCtx.onError((err) => {
        logError('洗牌音效播放错误:', err);
        wx.showToast({
          title: '洗牌音效播放失败',
          icon: 'none',
          duration: 1000
        });
      });
      
      // 开始播放
      shuffleAudioCtx.play();
      logInfo('已调用 shuffleAudioCtx.play()');
      
    } catch (error) {
      logError('洗牌音效播放异常:', error);
      wx.showToast({
        title: '洗牌音效播放异常',
        icon: 'none',
        duration: 1000
      });
    }
  },

  // 切换到指定模式（清空动画并重绘对应选项）
  switchToMode(newModeIndex) {
    const newMode = this.data.modes[newModeIndex];
    
    // 清空所有动画帧
    this.clearAllAnimations();
    
    // 同步更新所有模式相关状态
    this.setData({
      currentMode: newMode,
      currentModeIndex: newModeIndex,
      displayModeIndex: newModeIndex, // 确保显示和实际模式同步
      result: '???',
      coinResult: '',
      cardsResult: '',
      // 重置动画状态
      spinning: false,
      coinFlipping: false,

      isKnocking: false,
      showGongdeTip: false,
      isShaking: false,
      showFortuneStick: false,
      // 重置粒子效果和结果突出
      showParticles: false,
      particles: [],
      resultSectorIndex: -1,
      // 关闭设置菜单
      showSettingsMenu: false
    });

    // 根据新模式初始化对应的Canvas并绘制
    if (newMode === 'wheel') {
      this.createCanvasContext();
    } else if (newMode === 'coin') {
      this.createCoinCanvas();

    } else if (newMode === 'cards') {
      this.createCardsCanvas();
    } else if (newMode === 'muyu') {
      this.createMuyuCanvas();
    } else if (newMode === 'fortune') {
      this.createFortuneCanvas();
    }
  },

  // 清空所有动画帧
  clearAllAnimations() {
    if (this.animationFrame) {
      clearTimeout(this.animationFrame);
      this.animationFrame = null;
    }
    if (this.coinAnimationFrame) {
      clearTimeout(this.coinAnimationFrame);
      this.coinAnimationFrame = null;
    }

    if (this.cardsAnimationFrame) {
      clearTimeout(this.cardsAnimationFrame);
      this.cardsAnimationFrame = null;
    }
  },

  // 创建抛硬币Canvas上下文
  createCoinCanvas() {
    const query = wx.createSelectorQuery();
    query.select('#coinCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        if (!res[0]) return;
        
        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        const dpr = wx.getSystemInfoSync().pixelRatio;
        
        canvas.width = res[0].width * dpr;
        canvas.height = res[0].height * dpr;
        ctx.scale(dpr, dpr);
        
        this.setData({
          coinCanvas: canvas,
          coinCtx: ctx
        });
        
        this.drawCoin();
      });
  },



  // 绘制硬币（初始正面朝上）
  drawCoin(isFlipping = false, flipAngle = 0, finalSide = null) {
    const ctx = this.data.coinCtx;
    if (!ctx) return;
    
    const canvas = this.data.coinCanvas;
    const width = canvas.width / wx.getSystemInfoSync().pixelRatio;
    const height = canvas.height / wx.getSystemInfoSync().pixelRatio;
    const centerX = width / 2;
    const centerY = height / 2;
    const radius = Math.min(width, height) / 4;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 绘制幸运感背景效果
    this.drawLuckyBackground(ctx, centerX, centerY, width, height);
    
    // 硬币位置（翻转时增加更大的垂直偏移）
    let coinY = centerY;
    if (isFlipping) {
      // 增强抛物线效果，使硬币抛得更高
      coinY = centerY - Math.abs(Math.sin(flipAngle * 3)) * 150; // 从100增加到150
    }
    
    // 绘制硬币阴影（随着硬币高度动态调整）
    const shadowOffset = isFlipping ? Math.abs(Math.sin(flipAngle * 3)) * 30 : 0;
    ctx.beginPath();
    ctx.ellipse(centerX, centerY + 15 + shadowOffset, radius + 5, 8, 0, 0, 2 * Math.PI);
    ctx.fillStyle = `rgba(0, 0, 0, ${0.3 - shadowOffset * 0.005})`; // 阴影随高度变淡
    ctx.fill();
    
    // 绘制硬币主体
    ctx.save();
    ctx.translate(centerX, coinY);
    
    // 翻转时的旋转效果
    if (isFlipping) {
      ctx.rotate(flipAngle);
    }
    
    // 判断显示正面还是反面
    let showFront = true;
    if (isFlipping) {
      // 根据角度判断正反面
      const normalizedAngle = (flipAngle % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
      showFront = normalizedAngle < Math.PI;
    } else if (finalSide !== null) {
      // 如果指定了最终面，则使用指定的面
      showFront = finalSide === '正面';
    }
    
    // 绘制精美的硬币边框
    this.drawCoinBorder(ctx, radius);
    
    // 绘制正面或反面图案
    if (showFront) {
      // 正面：绘制幸运星
      this.drawLuckyStarCoin(ctx, radius);
    } else {
      // 反面：绘制花朵
      this.drawLuckyFlower(ctx, radius);
    }
    
    ctx.restore();
  },

  // 绘制精美的硬币边框
  drawCoinBorder(ctx, radius) {
    // 外圈金色渐变
    const outerGradient = ctx.createRadialGradient(0, 0, radius * 0.8, 0, 0, radius);
    outerGradient.addColorStop(0, '#FFD700');
    outerGradient.addColorStop(0.7, '#FFA500');
    outerGradient.addColorStop(1, '#FF8C00');
    
    ctx.beginPath();
    ctx.arc(0, 0, radius, 0, 2 * Math.PI);
    ctx.fillStyle = outerGradient;
    ctx.fill();
    
    // 外边框
    ctx.strokeStyle = '#B8860B';
    ctx.lineWidth = 4;
    ctx.stroke();
    
    // 内圈渐变背景
    const innerGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, radius * 0.85);
    innerGradient.addColorStop(0, '#FFF8DC');
    innerGradient.addColorStop(0.6, '#F0E68C');
    innerGradient.addColorStop(1, '#DAA520');
    
    ctx.beginPath();
    ctx.arc(0, 0, radius * 0.85, 0, 2 * Math.PI);
    ctx.fillStyle = innerGradient;
    ctx.fill();
    
    // 内边框装饰
    ctx.strokeStyle = '#CD853F';
    ctx.lineWidth = 2;
    ctx.stroke();
    
    // 添加装饰性圆点
    ctx.fillStyle = '#B8860B';
    for (let i = 0; i < 12; i++) {
      const angle = (i / 12) * Math.PI * 2;
      const dotX = Math.cos(angle) * radius * 0.9;
      const dotY = Math.sin(angle) * radius * 0.9;
      ctx.beginPath();
      ctx.arc(dotX, dotY, 2, 0, 2 * Math.PI);
      ctx.fill();
    }
  },

  // 绘制幸运星（硬币正面）
  drawLuckyStarCoin(ctx, radius) {
    const starSize = radius * 0.6;
    
    // 星星渐变
    const starGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, starSize);
    starGradient.addColorStop(0, '#FFFF00');
    starGradient.addColorStop(0.5, '#FFD700');
    starGradient.addColorStop(1, '#FFA500');
    
    ctx.fillStyle = starGradient;
    
    // 绘制五角星
    ctx.beginPath();
    for (let i = 0; i < 5; i++) {
      const angle = (i * 4 * Math.PI) / 5 - Math.PI / 2;
      const x = Math.cos(angle) * starSize;
      const y = Math.sin(angle) * starSize;
      if (i === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }
    }
    ctx.closePath();
    ctx.fill();
    
    // 星星边框
    ctx.strokeStyle = '#FF8C00';
    ctx.lineWidth = 3;
    ctx.stroke();
    
    // 中心小星星
    ctx.fillStyle = '#FFFFFF';
    ctx.font = `bold ${starSize * 0.4}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('✦', 0, 0);
    
    // 添加闪光效果
    ctx.strokeStyle = '#FFFFFF';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(-starSize * 0.3, -starSize * 0.3);
    ctx.lineTo(starSize * 0.3, starSize * 0.3);
    ctx.moveTo(starSize * 0.3, -starSize * 0.3);
    ctx.lineTo(-starSize * 0.3, starSize * 0.3);
    ctx.stroke();
  },

  // 绘制幸运花朵（反面）
  drawLuckyFlower(ctx, radius) {
    const flowerSize = radius * 0.7;
    
    // 绘制花瓣
    const petalColors = ['#FF69B4', '#FF1493', '#DC143C', '#B22222', '#8B0000'];
    
    for (let i = 0; i < 8; i++) {
      ctx.save();
      ctx.rotate((i * Math.PI) / 4);
      
      // 花瓣渐变
      const petalGradient = ctx.createRadialGradient(0, -flowerSize * 0.4, 0, 0, -flowerSize * 0.4, flowerSize * 0.4);
      petalGradient.addColorStop(0, '#FFB6C1');
      petalGradient.addColorStop(0.5, '#FF69B4');
      petalGradient.addColorStop(1, '#FF1493');
      
      ctx.fillStyle = petalGradient;
      
      // 绘制花瓣（椭圆形）
      ctx.beginPath();
      ctx.ellipse(0, -flowerSize * 0.4, flowerSize * 0.2, flowerSize * 0.4, 0, 0, 2 * Math.PI);
      ctx.fill();
      
      // 花瓣边框
      ctx.strokeStyle = '#DC143C';
      ctx.lineWidth = 1;
      ctx.stroke();
      
      ctx.restore();
    }
    
    // 花心
    const centerGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, flowerSize * 0.15);
    centerGradient.addColorStop(0, '#FFFF00');
    centerGradient.addColorStop(0.7, '#FFD700');
    centerGradient.addColorStop(1, '#FFA500');
    
    ctx.fillStyle = centerGradient;
    ctx.beginPath();
    ctx.arc(0, 0, flowerSize * 0.15, 0, 2 * Math.PI);
    ctx.fill();
    
    // 花心边框
    ctx.strokeStyle = '#FF8C00';
    ctx.lineWidth = 2;
    ctx.stroke();
    
    // 花心装饰点
    ctx.fillStyle = '#FFFFFF';
    for (let i = 0; i < 6; i++) {
      const angle = (i / 6) * Math.PI * 2;
      const dotX = Math.cos(angle) * flowerSize * 0.08;
      const dotY = Math.sin(angle) * flowerSize * 0.08;
      ctx.beginPath();
      ctx.arc(dotX, dotY, 1, 0, 2 * Math.PI);
      ctx.fill();
    }
  },

  // 抛硬币动画
  flipCoin() {
    if (this.data.coinFlipping) return;
    // 播放抛硬币音效
    this.playCoinSound();
    
    this.setData({ coinFlipping: true, coinResult: '' });
    
    const duration = 2000; // 增加动画时间到2秒
    const startTime = Date.now();
    let flipAngle = 0;
    
    const animate = () => {
      const currentTime = Date.now();
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);
      
      if (progress < 1) {
        // 计算翻转角度，增加更多旋转圈数
        const flipAngle = progress * Math.PI * 12; // 从8圈增加到10圈翻转
        this.drawCoin(true, flipAngle);
        this.coinAnimationFrame = setTimeout(animate, 16);
      } else {
        // 动画结束，随机决定结果
        const finalResult = Math.random() > 0.5 ? '正面' : '反面';
        
        // 根据结果显示对应图案
        this.drawCoin(false, 0, finalResult);
        
        // 更新结果显示文本
        const resultText = finalResult === '正面' ? '正面 ✦ 幸运星' : '反面 ❀ 幸运花';
        
        this.setData({ 
          coinFlipping: false,
          coinResult: resultText
        });
        
        // 保存历史记录
        this.saveGameHistory('coin', '抛硬币', resultText);
        
        // 添加每日首次奖励
        this.addModeReward('coin', '抛', 'hasCoinToday');
        
        // 振动反馈
        if (app.globalData.vibrateEnabled) {
          wx.vibrateShort();
        }
      }
    };
    
    animate();
  },



  // 创建翻牌子Canvas上下文
  createCardsCanvas() {
    // 等待DOM渲染完成
    setTimeout(() => {
      const query = wx.createSelectorQuery();
      query.select('#cardsCanvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (!res[0]) {
            logInfo('cardsCanvas获取失败');
            return;
          }
          
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          const dpr = wx.getSystemInfoSync().pixelRatio;
          
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
          
          logInfo('cardsCanvas初始化成功:', res[0].width, res[0].height);
          
          this.setData({
            cardsCanvas: canvas,
            cardsCtx: ctx
          });
          
          this.initCards();
          this.drawCards();
        });
    }, 100); // 等待100毫秒让DOM渲染完成
  },

  // 初始化牌子数据
  initCards() {
    const { wheelItems } = this.data;
    const cards = wheelItems.map((item, index) => ({
      id: index,
      content: item.text,
      color: item.color,
      isFlipped: false,
      x: 0,
      y: 0,
      width: 0,
      height: 0
    }));
    
    // 打乱牌子顺序
    this.shuffleArray(cards);
    
    this.setData({
      cards,
      flippedCards: []
    });
  },

  // 打乱数组顺序
  shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
  },

  // 绘制牌子
  drawCards() {
    const { cardsCtx, cards } = this.data;
    if (!cardsCtx || !cards.length) {
      logInfo('无法绘制牌子:', !!cardsCtx, cards.length);
      return;
    }
    
    const canvas = this.data.cardsCanvas;
    const canvasWidth = canvas.width / wx.getSystemInfoSync().pixelRatio;
    const canvasHeight = canvas.height / wx.getSystemInfoSync().pixelRatio;
    
    // logInfo('Canvas尺寸:', canvasWidth, canvasHeight);
    
    // 清空画布
    cardsCtx.clearRect(0, 0, canvasWidth, canvasHeight);
    
    // 绘制幸运感背景效果
    this.drawLuckyBackground(cardsCtx, canvasWidth / 2, canvasHeight / 2, canvasWidth, canvasHeight);
    
    // 计算牌子布局
    const cardCount = cards.length;
    const maxCardsPerRow = Math.min(4, cardCount); // 最多4列
    const rows = Math.ceil(cardCount / maxCardsPerRow);
    
    const padding = 30; // 增加上下间距
    const availableWidth = canvasWidth - padding * 2;
    const availableHeight = canvasHeight - padding * 2;
    
    const cardWidth = (availableWidth - (maxCardsPerRow - 1) * 15) / maxCardsPerRow;
    const cardHeight = Math.min(cardWidth * 1.2, (availableHeight - (rows - 1) * 15) / rows);
    
    logInfo('牌子尺寸计算:', {
      cardCount, maxCardsPerRow, rows, cardWidth, cardHeight, padding
    });
    
    // 更新牌子位置和尺寸
    cards.forEach((card, index) => {
      const row = Math.floor(index / maxCardsPerRow);
      const col = index % maxCardsPerRow;
      const cardsInThisRow = Math.min(maxCardsPerRow, cardCount - row * maxCardsPerRow);
      
      // 居中对齐
      const rowStartX = (canvasWidth - (cardsInThisRow * cardWidth + (cardsInThisRow - 1) * 15)) / 2;
      
      card.x = rowStartX + col * (cardWidth + 15);
      card.y = padding + row * (cardHeight + 15);
      card.width = cardWidth;
      card.height = cardHeight;
      
      // logInfo(`牌子${index}位置:`, card.x, card.y, card.width, card.height);
      
      this.drawSingleCard(cardsCtx, card);
    });
    
    logInfo('牌子绘制完成');
  },

  // 绘制单个牌子
  drawSingleCard(ctx, card) {
    const { x, y, width, height, isFlipped, content, color } = card;
    
    ctx.save();
    
    // 绘制牌子阴影（更柔和）
    ctx.shadowColor = 'rgba(0, 0, 0, 0.15)';
    ctx.shadowBlur = 8;
    ctx.shadowOffsetX = 3;
    ctx.shadowOffsetY = 3;
    ctx.fillStyle = 'rgba(0, 0, 0, 0.08)';
    ctx.fillRect(x, y, width, height);
    
    if (isFlipped) {
      // 翻开的牌子 - 使用转盘颜色，增加幸运主题效果
      // 绘制渐变背景
      const gradient = ctx.createLinearGradient(x, y, x + width, y + height);
      gradient.addColorStop(0, color);
      gradient.addColorStop(1, this.adjustColorBrightness(color, -30));
      ctx.fillStyle = gradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制高光效果
      const highlightGradient = ctx.createLinearGradient(x, y, x + width * 0.6, y + height * 0.6);
      highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.4)');
      highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
      ctx.fillStyle = highlightGradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制幸运星装饰
      this.drawLuckyStarOnCard(ctx, x + width * 0.15, y + height * 0.15, Math.min(width, height) * 0.1);
      this.drawLuckyStarOnCard(ctx, x + width * 0.85, y + height * 0.85, Math.min(width, height) * 0.1);
      
      // 绘制精美边框
      ctx.strokeStyle = 'rgba(255, 255, 255, 0.9)';
      ctx.lineWidth = 2;
      ctx.strokeRect(x, y, width, height);
      
      // 绘制内容文字（自适应字体大小和换行）
      ctx.fillStyle = '#fff';
      ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
      ctx.shadowBlur = 3;
      ctx.shadowOffsetX = 2;
      ctx.shadowOffsetY = 2;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      
      // 使用新的自适应文字绘制函数
      this.drawAdaptiveTextWithEmojis(ctx, content, x + width / 2, y + height / 2, width * 0.8, height * 0.8);
    } else {
      // 未翻开的牌子 - 优雅的幸运主题设计，但不比翻开的牌更显眼
      // 绘制渐变背景
      const gradient = ctx.createLinearGradient(x, y, x + width, y + height);
      gradient.addColorStop(0, '#a0a0a0'); // 灰色渐变，低调但有质感
      gradient.addColorStop(1, '#808080');
      ctx.fillStyle = gradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制微妙的纹理效果
      ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
      for (let i = 0; i < 20; i++) {
        const dotX = x + Math.random() * width;
        const dotY = y + Math.random() * height;
        const dotSize = Math.random() * 2;
        ctx.beginPath();
        ctx.arc(dotX, dotY, dotSize, 0, Math.PI * 2);
        ctx.fill();
      }
      
      // 绘制精致边框
      ctx.strokeStyle = '#606060';
      ctx.lineWidth = 1.5;
      ctx.strokeRect(x, y, width, height);
      
      // 绘制幸运问号（使用相对低调的颜色）
      ctx.fillStyle = '#d0d0d0';
      ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
      ctx.shadowBlur = 2;
      ctx.shadowOffsetX = 1;
      ctx.shadowOffsetY = 1;
      ctx.font = `bold ${Math.min(width, height) * 0.4}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('?', x + width / 2, y + height / 2);
      
      // 添加微妙的光效（比之前更低调）
      const lightGradient = ctx.createRadialGradient(
        x + width * 0.3, y + height * 0.3, 0,
        x + width * 0.3, y + height * 0.3, width * 0.4
      );
      lightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.2)');
      lightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
      ctx.fillStyle = lightGradient;
      ctx.fillRect(x, y, width, height);
    }
    
    // 清除阴影设置
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    
    ctx.restore();
  },

  // 调整颜色亮度
  adjustColorBrightness(hex, percent) {
    const num = parseInt(hex.replace('#', ''), 16);
    const amt = Math.round(2.55 * percent);
    const R = (num >> 16) + amt;
    const G = (num >> 8 & 0x00FF) + amt;
    const B = (num & 0x0000FF) + amt;
    return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
      (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
      (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
  },

  // 处理牌子点击
  onCardTouch(e) {
    logInfo('牌子触摸事件被触发');
    
    const { cardsCtx, cards } = this.data;
    if (!cardsCtx || !cards.length) {
      logInfo('牌子数据或上下文不存在:', !!cardsCtx, cards.length);
      return;
    }
    
    // 防止双击
    if (this.cardTouchLock) return;
    this.cardTouchLock = true;
    setTimeout(() => {
      this.cardTouchLock = false;
    }, 300);
    
    // 使用微信小程序的 API 获取 Canvas 位置信息
    const query = wx.createSelectorQuery();
    query.select('#cardsCanvas')
      .boundingClientRect((rect) => {
        if (!rect) {
          logInfo('无法获取Canvas位置信息');
          return;
        }
        
        const touch = e.touches[0];
        
        // 计算相对于Canvas的触摸坐标（无需dpr处理）
        const x = touch.clientX - rect.left;
        const y = touch.clientY - rect.top;
        
        // logInfo('点击坐标:', x, y);
        // logInfo('Canvas位置:', rect);
        // logInfo('牌子数据:', cards.map(card => ({
        //   x: card.x, y: card.y, w: card.width, h: card.height, flipped: card.isFlipped
        // })));
        
        // 检查点击了哪张牌
        const clickedCardIndex = cards.findIndex((card, index) => {
          const inCard = x >= card.x && x <= card.x + card.width &&
                        y >= card.y && y <= card.y + card.height;
          // logInfo(`牌子${index}:`, card.x, card.y, card.width, card.height, '是否命中:', inCard);
          return inCard;
        });
        
        logInfo('点击的牌子索引:', clickedCardIndex);
        
        if (clickedCardIndex !== -1 && !cards[clickedCardIndex].isFlipped) {
          logInfo('翻开牌子:', cards[clickedCardIndex].content);
          
          // 播放翻牌子音效
          this.playCardsFlipSound();
          
          // 翻开牌子
          cards[clickedCardIndex].isFlipped = true;
          const flippedCards = [...this.data.flippedCards, clickedCardIndex];
          
          this.setData({
            cards,
            flippedCards,
            cardsResult: cards[clickedCardIndex].content
          });
          
          // 保存历史记录
          this.saveGameHistory('cards', `${this.data.wheelName}`, cards[clickedCardIndex].content);
          
          // 添加每日首次奖励
          this.addModeReward('cards', '翻', 'hasCardsToday');
          
          this.drawCards();
        } else if (clickedCardIndex !== -1) {
          logInfo('牌子已翻开');
        } else {
          logInfo('未命中任何牌子');
        }
      })
      .exec();
  },

  // 重置牌子
  resetCards() {
    logInfo('重置牌子被点击');
    
    this.setData({
      cardsResult: ''
    });
    
    this.initCards();
    this.drawCards();
  },

  // 播放翻牌子音效（修复版本 - 支持快速连续播放）
  playCardsFlipSound() {
    const { cardsAudioCtx, soundEnabled } = this.data;
    
    // 检查全局声音开关和音效上下文是否存在
    if (!soundEnabled || !cardsAudioCtx) {
      logInfo('翻牌子音效未播放：', { soundEnabled, hasAudioCtx: !!cardsAudioCtx });
      return;
    }
    
    try {
      // 创建新的音频上下文来支持快速连续播放
      const newAudioCtx = wx.createInnerAudioContext();
      newAudioCtx.src = '/audio/fanpaizi.mp3';
      newAudioCtx.loop = false;
      newAudioCtx.autoplay = false;
      newAudioCtx.volume = 1.0;
      
      // 播放完成后自动销毁
      newAudioCtx.onEnded(() => {
        newAudioCtx.destroy();
      });
      
      newAudioCtx.onError((err) => {
        logInfo('翻牌子音效播放失败：', err);
        newAudioCtx.destroy();
        wx.showToast({
          title: '翻牌子音效播放失败',
          icon: 'none',
          duration: 800
        });
      });
      
      // 添加成功监听（可选）
      newAudioCtx.onPlay(() => {
        logInfo('翻牌子音效播放成功');
      });
      
      // 执行播放
      newAudioCtx.play();
      
      logInfo('翻牌子音效开始播放（快速连续播放模式）');
      
    } catch (error) {
      logError('翻牌子音效播放异常:', error);
    }
  },

  // 播放幸运抽签音效（支持快速连续播放）
  playFortuneSound() {
    const { fortuneAudioCtx, soundEnabled } = this.data;
    
    // 检查全局声音开关和音效上下文是否存在
    if (!soundEnabled || !fortuneAudioCtx) {
      logInfo('幸运抽签音效未播放：', { soundEnabled, hasAudioCtx: !!fortuneAudioCtx });
      return;
    }
    
    try {
      // 创建新的音频上下文来支持快速连续播放
      const newAudioCtx = wx.createInnerAudioContext();
      newAudioCtx.src = '/audio/chouqian.mp3';
      newAudioCtx.loop = false;
      newAudioCtx.autoplay = false;
      newAudioCtx.volume = 1.0;
      
      // 播放完成后自动销毁
      newAudioCtx.onEnded(() => {
        newAudioCtx.destroy();
      });
      
      newAudioCtx.onError((err) => {
        logInfo('幸运抽签音效播放失败：', err);
        newAudioCtx.destroy();
        wx.showToast({
          title: '幸运抽签音效播放失败',
          icon: 'none',
          duration: 800
        });
      });
      
      // 添加成功监听（可选）
      newAudioCtx.onPlay(() => {
        logInfo('幸运抽签音效播放成功');
      });
      
      // 执行播放
      newAudioCtx.play();
      
      logInfo('幸运抽签音效开始播放（快速连续播放模式）');
      
    } catch (error) {
      logError('幸运抽签音效播放异常:', error);
    }
  },

  // ==================== 减压敲模式 ====================
  
  // 创建减压敲Canvas上下文
  createMuyuCanvas() {
    // 等待DOM渲染完成
    setTimeout(() => {
      const query = wx.createSelectorQuery();
      query.select('#muyuCanvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (!res[0]) {
            logInfo('muyuCanvas获取失败');
            return;
          }
          
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          const dpr = wx.getSystemInfoSync().pixelRatio;
          
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
          
          logInfo('muyuCanvas初始化成功:', res[0].width, res[0].height);
          
          this.setData({
            muyuCanvas: canvas,
            muyuCtx: ctx
          });
          
          // 检查音效状态
          this.checkMuyuAudioStatus();
          
          this.drawMuyu();
        });
    }, 100);
  },

  // 绘制木鱼和木鱼槌
  drawMuyu() {
    const { muyuCtx, gongde, isKnocking, showGongdeTip } = this.data;
    if (!muyuCtx) return;
    
    const canvas = this.data.muyuCanvas;
    const canvasWidth = canvas.width / wx.getSystemInfoSync().pixelRatio;
    const canvasHeight = canvas.height / wx.getSystemInfoSync().pixelRatio;
    
    // 清空画布
    muyuCtx.clearRect(0, 0, canvasWidth, canvasHeight);
    
    const centerX = canvasWidth / 2;
    const centerY = canvasHeight / 2;
    
    // 绘制幸运感背景效果
    this.drawLuckyBackground(muyuCtx, centerX, centerY, canvasWidth, canvasHeight);
    
    // 重新调整布局，确保功德计数器不被遮挡
    // 功德计数器位置：离顶部保留足够空间
    const gongdeCounterY = Math.max(60, canvasHeight * 0.15);
    
    // 木鱼位置：在屏幕中下部
    const muyuY = centerY + 60;
    
    // 木鱼槌位置：在木鱼上方，水平放置
    const hammerX = centerX;
    const hammerY = muyuY - 80; // 在木鱼上方80px
    
    // 绘制木鱼
    this.drawMuyuBody(muyuCtx, centerX, muyuY, isKnocking);
    
    // 绘制木鱼槌（水平放置在木鱼上方）
    this.drawMuyuHammer(muyuCtx, hammerX, hammerY, isKnocking);
    
    // 绘制功德计数器
    this.drawGongdeCounter(muyuCtx, centerX, gongdeCounterY, gongde);
    
    // 绘制功德+1提示（在木鱼上方）
    if (showGongdeTip) {
      this.drawGongdeTip(muyuCtx, centerX, muyuY - 40);
    }
  },

  // 绘制背景光晕
  drawMuyuBackground(ctx, centerX, centerY, width, height) {
    // 创建幸运主题的渐变背景
    const gradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, Math.max(width, height) * 0.8
    );
    gradient.addColorStop(0, 'rgba(255, 215, 0, 0.1)'); // 金色光晕
    gradient.addColorStop(0.3, 'rgba(255, 193, 7, 0.05)');
    gradient.addColorStop(1, 'rgba(255, 152, 0, 0.02)');
    
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    
    // 绘制一些装饰性的光点
    for (let i = 0; i < 6; i++) {
      const angle = (i / 6) * Math.PI * 2;
      const radius = 200 + Math.sin(Date.now() * 0.001 + i) * 20;
      const x = centerX + Math.cos(angle) * radius;
      const y = centerY + Math.sin(angle) * radius;
      
      ctx.beginPath();
      ctx.arc(x, y, 3 + Math.sin(Date.now() * 0.002 + i) * 2, 0, 2 * Math.PI);
      ctx.fillStyle = `rgba(255, 215, 0, ${0.3 + Math.sin(Date.now() * 0.003 + i) * 0.2})`;
      ctx.fill();
    }
  },

  // 绘制木鱼本体
  drawMuyuBody(ctx, centerX, centerY, isKnocking) {
    ctx.save();
    
    // 敲击时的微小振动
    if (isKnocking) {
      ctx.translate(
        (Math.random() - 0.5) * 4,
        (Math.random() - 0.5) * 4
      );
    }
    
    const size = 120;
    
    // 绘制木鱼阴影
    ctx.fillStyle = 'rgba(139, 69, 19, 0.2)';
    ctx.beginPath();
    ctx.ellipse(centerX + 3, centerY + size * 0.8 + 3, size * 0.8, size * 0.3, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制木鱼主体（椰子壳颜色）
    const gradient = ctx.createRadialGradient(
      centerX - size * 0.2, centerY - size * 0.2, 0,
      centerX, centerY, size
    );
    gradient.addColorStop(0, '#DEB887'); // 浅棕色
    gradient.addColorStop(0.6, '#CD853F'); // 秘鲁色
    gradient.addColorStop(1, '#8B4513'); // 马鞍棕色
    
    ctx.fillStyle = gradient;
    ctx.beginPath();
    ctx.ellipse(centerX, centerY, size * 0.7, size * 0.6, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制木鱼纹理
    ctx.strokeStyle = '#A0522D';
    ctx.lineWidth = 2;
    for (let i = 0; i < 3; i++) {
      ctx.beginPath();
      ctx.ellipse(centerX, centerY + i * 15 - 15, size * 0.6, size * 0.1, 0, 0, 2 * Math.PI);
      ctx.stroke();
    }
    
    // 绘制木鱼上的金色装饰
    ctx.fillStyle = '#FFD700';
    ctx.beginPath();
    ctx.ellipse(centerX, centerY - 20, size * 0.3, size * 0.15, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制中间的"功德"字样
    ctx.fillStyle = '#8B4513';
    ctx.font = 'bold 24px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('功德', centerX, centerY + 10);
    
    ctx.restore();
  },

  // 绘制木鱼槌（完整的横向锤子设计）
  drawMuyuHammer(ctx, centerX, centerY, isKnocking) {
    ctx.save();
    
    // 锤子尺寸参数
    const hammerTotalLength = 140; // 锤子总长度
    const handleLength = 90; // 手柄长度
    const handleWidth = 14; // 手柄宽度
    const hammerHeadWidth = 45; // 锤头宽度
    const hammerHeadHeight = 35; // 锤头高度
    
    // 敲击时整个锤子向下移动
    let offsetY = 0;
    if (isKnocking) {
      offsetY = 20; // 整个锤子向下移动20px
    }
    
    const currentCenterY = centerY + offsetY;
    
    // 调整锤子水平位置，让槌头中心对准木鱼中心
    // 槌头应该在木鱼正上方，所以槌头中心 = centerX
    // 锤头宽度45，所以槌头左边缘 = centerX - 22.5
    // 手柄在锤头右侧，所以手柄起始位置 = centerX + 22.5
    const hammerHeadCenterX = centerX; // 槌头中心对准木鱼中心
    const hammerHeadX = hammerHeadCenterX - hammerHeadWidth / 2;
    const handleStartX = hammerHeadCenterX + hammerHeadWidth / 2;
    const handleEndX = handleStartX + handleLength;
    const handleY = currentCenterY;
    const hammerHeadY = currentCenterY;
    
    // 绘制手柄（木质纹理）
    const handleGradient = ctx.createLinearGradient(
      handleStartX, handleY - handleWidth/2,
      handleStartX, handleY + handleWidth/2
    );
    handleGradient.addColorStop(0, '#D2B48C'); // 浅棕色
    handleGradient.addColorStop(0.5, '#A0522D'); // 马鞍棕色
    handleGradient.addColorStop(1, '#8B4513'); // 深棕色
    
    ctx.fillStyle = handleGradient;
    ctx.fillRect(
      handleStartX,
      handleY - handleWidth/2,
      handleLength,
      handleWidth
    );
    
    // 绘制手柄纹理线条
    ctx.strokeStyle = '#654321';
    ctx.lineWidth = 1;
    for (let i = 1; i < 4; i++) {
      const x = handleStartX + (handleLength / 4) * i;
      ctx.beginPath();
      ctx.moveTo(x, handleY - handleWidth/2);
      ctx.lineTo(x, handleY + handleWidth/2);
      ctx.stroke();
    }
    
    // 绘制手柄边框
    ctx.strokeStyle = '#5D4037';
    ctx.lineWidth = 2;
    ctx.strokeRect(
      handleStartX,
      handleY - handleWidth/2,
      handleLength,
      handleWidth
    );
    
    // 绘制锤头（金属质感）
    const headGradient = ctx.createLinearGradient(
      hammerHeadX, hammerHeadY - hammerHeadHeight/2,
      hammerHeadX, hammerHeadY + hammerHeadHeight/2
    );
    headGradient.addColorStop(0, '#FFD700'); // 金色
    headGradient.addColorStop(0.3, '#FFA500'); // 橙色
    headGradient.addColorStop(0.7, '#FF8C00'); // 深橙色
    headGradient.addColorStop(1, '#D4A017'); // 深金色
    
    ctx.fillStyle = headGradient;
    ctx.fillRect(
      hammerHeadX,
      hammerHeadY - hammerHeadHeight/2,
      hammerHeadWidth,
      hammerHeadHeight
    );
    
    // 绘制锤头边框
    ctx.strokeStyle = '#B8860B';
    ctx.lineWidth = 2;
    ctx.strokeRect(
      hammerHeadX,
      hammerHeadY - hammerHeadHeight/2,
      hammerHeadWidth,
      hammerHeadHeight
    );
    
    // 绘制锤头上的装饰纹理
    ctx.strokeStyle = '#FF6347';
    ctx.lineWidth = 1.5;
    // 水平线条
    for (let i = 1; i < 3; i++) {
      const y = hammerHeadY - hammerHeadHeight/2 + (hammerHeadHeight / 3) * i;
      ctx.beginPath();
      ctx.moveTo(hammerHeadX + 5, y);
      ctx.lineTo(hammerHeadX + hammerHeadWidth - 5, y);
      ctx.stroke();
    }
    
    // 绘制锤头高光效果
    ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
    ctx.fillRect(
      hammerHeadX + 3,
      hammerHeadY - hammerHeadHeight/2 + 3,
      hammerHeadWidth * 0.3,
      hammerHeadHeight * 0.4
    );
    
    // 绘制连接部分（锤头与手柄的连接）
    ctx.fillStyle = '#A0522D';
    ctx.fillRect(
      handleStartX - 4,
      handleY - handleWidth/2 - 2,
      8,
      handleWidth + 4
    );
    
    // 绘制手柄末端的防滑纹理
    ctx.strokeStyle = '#654321';
    ctx.lineWidth = 2;
    for (let i = 0; i < 3; i++) {
      const x = handleEndX - 15 + i * 3;
      ctx.beginPath();
      ctx.moveTo(x, handleY - handleWidth/2);
      ctx.lineTo(x, handleY + handleWidth/2);
      ctx.stroke();
    }
    
    ctx.restore();
  },

  // 绘制功德计数器
  drawGongdeCounter(ctx, centerX, centerY, gongde) {
    // 调整尺寸，让功德计数器更显眼
    const counterWidth = 200; // 增加宽度
    const counterHeight = 50;  // 增加高度
    const radius = 25;
    
    // 绘制背景框
    const bgGradient = ctx.createLinearGradient(
      centerX - counterWidth/2, centerY - counterHeight/2,
      centerX + counterWidth/2, centerY + counterHeight/2
    );
    bgGradient.addColorStop(0, 'rgba(255, 215, 0, 0.9)'); // 提高不透明度
    bgGradient.addColorStop(0.5, 'rgba(255, 193, 7, 0.95)');
    bgGradient.addColorStop(1, 'rgba(255, 215, 0, 0.9)');
    
    ctx.fillStyle = bgGradient;
    
    // 手动绘制圆角矩形
    const x = centerX - counterWidth/2;
    const y = centerY - counterHeight/2;
    const width = counterWidth;
    const height = counterHeight;
    
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    ctx.fill();
    
    // 绘制边框
    ctx.strokeStyle = '#FF6347';
    ctx.lineWidth = 3; // 增加边框宽度
    ctx.stroke();
    
    // 添加内阴影效果
    ctx.strokeStyle = 'rgba(139, 69, 19, 0.3)';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(x + radius + 3, y + 3);
    ctx.lineTo(x + width - radius - 3, y + 3);
    ctx.quadraticCurveTo(x + width - 3, y + 3, x + width - 3, y + radius + 3);
    ctx.lineTo(x + width - 3, y + height - radius - 3);
    ctx.stroke();
    
    // 绘制文字
    ctx.fillStyle = '#8B4513';
    ctx.font = 'bold 22px serif'; // 增大字体
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 添加文字阴影
    ctx.shadowColor = 'rgba(255, 255, 255, 0.8)';
    ctx.shadowBlur = 2;
    ctx.shadowOffsetX = 1;
    ctx.shadowOffsetY = 1;
    
    ctx.fillText(`累计功德: ${gongde}`, centerX, centerY);
    
    // 清除阴影设置
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
  },

  // 绘制功德+1提示
  drawGongdeTip(ctx, centerX, centerY) {
    ctx.save();
    
    // 添加发光效果
    ctx.shadowColor = '#FFD700';
    ctx.shadowBlur = 10;
    
    ctx.fillStyle = '#FF6347';
    ctx.font = 'bold 32px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('功德+1', centerX, centerY);
    
    ctx.restore();
  },

  // 处理木鱼点击（点击木鱼或木鱼槌都可以触发敲击）
  onMuyuHammerTouch(e) {
    logInfo('木鱼区域被点击');
    
    if (this.data.isKnocking) return; // 防止重复点击
    
    // 获取点击位置，检查是否点击了木鱼或木鱼槌区域
    const query = wx.createSelectorQuery();
    query.select('#muyuCanvas')
      .boundingClientRect((rect) => {
        if (!rect) return;
        
        const touch = e.touches[0];
        const canvas = this.data.muyuCanvas;
        const canvasWidth = canvas.width / wx.getSystemInfoSync().pixelRatio;
        const canvasHeight = canvas.height / wx.getSystemInfoSync().pixelRatio;
        
        // 计算相对于Canvas的触摸坐标
        const x = touch.clientX - rect.left;
        const y = touch.clientY - rect.top;
        
        const centerX = canvasWidth / 2;
        const centerY = canvasHeight / 2;
        
        // 木鱼位置（在中下部）
        const muyuX = centerX;
        const muyuY = centerY + 60;
        const muyuRadius = 70; // 木鱼点击范围
        
        // 木鱼槌位置（在木鱼上方） - 更新为新的位置
        const hammerCenterX = centerX; // 槌头中心对准木鱼中心
        const hammerY = muyuY - 80;
        const hammerTotalWidth = 140; // 整个锤子的总宽度
        const hammerHeight = 40; // 锤子高度
        
        // 检查是否点击了木鱼
        const clickedMuyu = Math.sqrt((x - muyuX) ** 2 + (y - muyuY) ** 2) <= muyuRadius;
        
        // 检查是否点击了木鱼槌（矩形区域检测）
        const clickedHammer = x >= (hammerCenterX - hammerTotalWidth/2) && 
                             x <= (hammerCenterX + hammerTotalWidth/2) &&
                             y >= (hammerY - hammerHeight/2) && 
                             y <= (hammerY + hammerHeight/2);
        
        if (clickedMuyu || clickedHammer) {
          // 执行敲击动画
          this.performKnockAnimation();
        }
      })
      .exec();
  },
  
  // 执行敲击动画
  performKnockAnimation() {
    // 获取当前功德值并增加1
    const newGongde = this.data.gongde + 1;
    
    // 开始敲击动画
    this.setData({
      isKnocking: true,
      gongde: newGongde,
      showGongdeTip: true
    });
    
    // 保存功德值到本地存储
    wx.setStorageSync('gongde', newGongde);
    
    // 添加每日首次奖励
    this.addModeReward('muyu', '敲', 'hasMuyuToday');
    
    // 绘制敲击效果
    this.drawMuyu();
    
    // 播放敲击音效
    this.playMuyuSound();
    
    // 振动反馈
    if (app.globalData.vibrateEnabled) {
      wx.vibrateShort();
    }
    
    // 结束动画
    setTimeout(() => {
      this.setData({
        isKnocking: false
      });
      this.drawMuyu();
    }, 200);
    
    // 隐藏功德+1提示
    setTimeout(() => {
      this.setData({
        showGongdeTip: false
      });
      this.drawMuyu();
    }, 800);
  },

  // 播放木鱼敲击音效（修复版本 - 支持快速连续播放）
  playMuyuSound() {
    logInfo('开始播放木鱼音效...');
    logInfo('soundEnabled:', this.data.soundEnabled);
    logInfo('muyuAudioCtx:', !!this.data.muyuAudioCtx);
    
    // 检查是否开启声音和音效上下文是否存在
    if (!this.data.soundEnabled) {
      logInfo('声音开关已关闭，跳过音效播放');
      return;
    }
    
    if (!this.data.muyuAudioCtx) {
      logInfo('木鱼音效上下文不存在，尝试重新初始化...');
      this.initMuyuAudioContext();
      // 等待初始化完成后再播放
      setTimeout(() => {
        this.playMuyuSoundInternal();
      }, 100);
      return;
    }
    
    // 直接播放，支持快速连续播放
    this.playMuyuSoundInternal();
  },
  
  // 内部音效播放方法（优化版本 - 支持快速连续播放）
  playMuyuSoundInternal() {
    const audioCtx = this.data.muyuAudioCtx;
    if (!audioCtx) {
      logInfo('音效上下文初始化失败');
      return;
    }
    
    try {
      // 创建新的音频上下文来支持快速连续播放
      const newAudioCtx = wx.createInnerAudioContext();
      newAudioCtx.src = '/audio/muyu-sound.mp3';
      newAudioCtx.loop = false;
      newAudioCtx.autoplay = false;
      newAudioCtx.volume = 1.0;
      
      // 播放完成后自动销毁
      newAudioCtx.onEnded(() => {
        newAudioCtx.destroy();
      });
      
      newAudioCtx.onError((err) => {
        logError('木鱼音效播放错误:', err);
        newAudioCtx.destroy();
      });
      
      // 直接播放新实例
      newAudioCtx.play();
      logInfo('已调用 newAudioCtx.play() - 快速连续播放模式');
      
    } catch (error) {
      logError('木鱼音效播放异常:', error);
      // 在异常情况下尝试重新播放
      setTimeout(() => {
        try {
          audioCtx.seek(0);
          audioCtx.play();
        } catch (retryError) {
          logError('音效重试播放失败:', retryError);
        }
      }, 50);
    }
  },

  // 手动测试木鱼音效（供调试使用）
  testMuyuSound() {
    logInfo('手动测试木鱼音效...');
    this.playMuyuSound();
  },
  
  // 检查木鱼音效状态
  checkMuyuAudioStatus() {
    logInfo('=== 木鱼音效状态检查 ===');
    logInfo('声音开关:', this.data.soundEnabled);
    logInfo('全局声音开关:', app.globalData.soundEnabled);
    logInfo('木鱼音效上下文存在:', !!this.data.muyuAudioCtx);
    
    if (this.data.muyuAudioCtx) {
      logInfo('音效源路径:', this.data.muyuAudioCtx.src);
      logInfo('音效音量:', this.data.muyuAudioCtx.volume);
      logInfo('音效暂停状态:', this.data.muyuAudioCtx.paused);
    }
    
    // 如果声音开关开启但没有音效上下文，尝试重新初始化
    if (this.data.soundEnabled && !this.data.muyuAudioCtx) {
      logInfo('声音开启但没有音效上下文，尝试重新初始化...');
      this.initMuyuAudioContext();
    }
    
    logInfo('=== 状态检查完成 ===');
  },

  // 播放抛硬币音效
  playCoinSound() {
    logInfo('开始播放抛硬币音效...');
    logInfo('soundEnabled:', this.data.soundEnabled);
    logInfo('coinAudioCtx:', !!this.data.coinAudioCtx);
    
    // 检查是否开启声音和音效上下文是否存在
    if (!this.data.soundEnabled) {
      logInfo('声音开关已关闭，跳过音效播放');
      return;
    }
    
    if (!this.data.coinAudioCtx) {
      logInfo('抛硬币音效上下文不存在，尝试重新初始化...');
      this.initCoinAudioContext();
      // 等待初始化完成后再播放
      setTimeout(() => {
        this.playCoinSoundInternal();
      }, 100);
      return;
    }
    
    this.playCoinSoundInternal();
  },
  
  // 内部抛硬币音效播放方法
  playCoinSoundInternal() {
    const audioCtx = this.data.coinAudioCtx;
    if (!audioCtx) {
      logInfo('抛硬币音效上下文初始化失败');
      return;
    }
    
    try {
      // 重新设置播放位置到开始，以便可以重复播放
      audioCtx.seek(0);
      
      // 添加播放成功回调
      audioCtx.onPlay(() => {
        logInfo('抛硬币音效播放成功！');
      });
      
      // 添加播放结束回调
      audioCtx.onEnded(() => {
        logInfo('抛硬币音效播放结束');
      });
      
      // 添加错误回调
      audioCtx.onError((err) => {
        logError('抛硬币音效播放错误:', err);
        wx.showToast({
          title: '音效播放失败',
          icon: 'none',
          duration: 1000
        });
      });
      
      // 开始播放
      audioCtx.play();
      logInfo('已调用 audioCtx.play()');
      
    } catch (error) {
      logError('抛硬币音效播放异常:', error);
      wx.showToast({
        title: '音效播放异常',
        icon: 'none',
        duration: 1000
      });
    }
  },

  // 重置功德
  resetGongde() {
    logInfo('重置功德被点击');
    
    wx.showModal({
      title: '确认重置',
      content: '确定要重置功德值吗？',
      success: (res) => {
        if (res.confirm) {
          this.setData({
            gongde: 0
          });
          // 保存重置后的功德值
          wx.setStorageSync('gongde', 0);
          this.drawMuyu();
        }
      }
    });
  },

  // ==================== 幸运抽签模式 ====================
  
  // 创建幸运抽签 Canvas上下文
  createFortuneCanvas() {
    // 等待DOM渲染完成
    setTimeout(() => {
      const query = wx.createSelectorQuery();
      query.select('#fortuneCanvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (!res[0]) {
            logInfo('fortuneCanvas获取失败');
            return;
          }
          
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          const dpr = wx.getSystemInfoSync().pixelRatio;
          
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
          
          logInfo('fortuneCanvas初始化成功:', res[0].width, res[0].height);
          
          this.setData({
            fortuneCanvas: canvas,
            fortuneCtx: ctx
          });
          
          this.drawFortuneTube();
        });
    }, 100);
  },

  // 绘制签筒和竹签
  drawFortuneTube() {
    const { fortuneCtx, isShaking, showFortuneStick, fortuneResult, shakeIntensity, shakeSpeed } = this.data;
    if (!fortuneCtx) return;
    
    const canvas = this.data.fortuneCanvas;
    const canvasWidth = canvas.width / wx.getSystemInfoSync().pixelRatio;
    const canvasHeight = canvas.height / wx.getSystemInfoSync().pixelRatio;
    
    // 清空画布
    fortuneCtx.clearRect(0, 0, canvasWidth, canvasHeight);
    
    const centerX = canvasWidth / 2;
    const centerY = canvasHeight / 2;
    
    // 摇动时的偏移量（使用新的动画参数）
    let shakeOffsetX = 0;
    let shakeOffsetY = 0;
    if (isShaking && shakeIntensity !== undefined && shakeSpeed !== undefined) {
      const time = Date.now();
      shakeOffsetX = (Math.sin(time * 0.01 * shakeSpeed) * 15) * shakeIntensity;
      shakeOffsetY = (Math.cos(time * 0.008 * shakeSpeed) * 8) * shakeIntensity;
    }
    
    // 绘制背景光晕
    this.drawLuckyBackground(fortuneCtx, centerX, centerY, canvasWidth, canvasHeight);
    
    // 绘制签筒
    this.drawFortuneTubeBody(fortuneCtx, centerX + shakeOffsetX, centerY + shakeOffsetY, isShaking);
    
    // 绘制签文显示（最上层）
    if (showFortuneStick) {
      this.drawFortuneStick(fortuneCtx, centerX, centerY, fortuneResult);
    }
  },

  // 绘制背景光晕
  drawFortuneBackground(ctx, centerX, centerY, width, height) {
    // 创建更丰富的幸运主题光晕背景
    const gradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, Math.max(width, height) * 0.8
    );
    gradient.addColorStop(0, 'rgba(255, 215, 0, 0.15)'); // 金色光晕
    gradient.addColorStop(0.3, 'rgba(255, 99, 71, 0.08)'); // 红色光晕
    gradient.addColorStop(0.6, 'rgba(255, 165, 0, 0.05)'); // 橙色光晕
    gradient.addColorStop(1, 'rgba(220, 20, 60, 0.03)'); // 深红色光晕
    
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    
    // 绘制装饰性的幸运星星（增加闪烁效果和数量）
    const time = Date.now();
    for (let i = 0; i < 12; i++) {
      const angle = (i / 12) * Math.PI * 2 + time * 0.0003;
      const radius = 150 + Math.sin(time * 0.001 + i) * 40;
      const x = centerX + Math.cos(angle) * radius;
      const y = centerY + Math.sin(angle) * radius;
      
      // 星星大小和透明度变化
      const size = 3 + Math.sin(time * 0.002 + i) * 2;
      const alpha = 0.3 + Math.sin(time * 0.0015 + i) * 0.3;
      
      ctx.save();
      ctx.globalAlpha = alpha;
      this.drawStar(ctx, x, y, size, '#FFD700');
      ctx.restore();
    }
    
    // 添加额外的小星星点缀
    for (let i = 0; i < 20; i++) {
      const x = centerX + (Math.random() - 0.5) * width * 0.8;
      const y = centerY + (Math.random() - 0.5) * height * 0.8;
      const size = 1 + Math.random() * 2;
      const alpha = 0.2 + Math.random() * 0.3;
      
      ctx.save();
      ctx.globalAlpha = alpha;
      this.drawStar(ctx, x, y, size, '#FFFFFF');
      ctx.restore();
    }
  },

  // 绘制小星星
  drawStar(ctx, cx, cy, size, color) {
    ctx.save();
    ctx.translate(cx, cy);
    
    // 创建星星渐变
    const gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, size);
    gradient.addColorStop(0, '#FFFFFF');
    gradient.addColorStop(0.5, color);
    gradient.addColorStop(1, 'rgba(255, 215, 0, 0)');
    
    ctx.fillStyle = gradient;
    ctx.beginPath();
    
    // 绘制五角星
    for (let i = 0; i < 5; i++) {
      const outerAngle = (i * 2 * Math.PI) / 5 - Math.PI / 2;
      const innerAngle = ((i * 2 + 1) * Math.PI) / 5 - Math.PI / 2;
      
      const outerX = Math.cos(outerAngle) * size;
      const outerY = Math.sin(outerAngle) * size;
      const innerX = Math.cos(innerAngle) * (size * 0.4);
      const innerY = Math.sin(innerAngle) * (size * 0.4);
      
      if (i === 0) {
        ctx.moveTo(outerX, outerY);
      } else {
        ctx.lineTo(outerX, outerY);
      }
      ctx.lineTo(innerX, innerY);
    }
    
    ctx.closePath();
    ctx.fill();
    
    ctx.restore();
  },

  // 统一的幸运感背景绘制方法
  drawLuckyBackground(ctx, centerX, centerY, width, height) {
    // 创建幸运主题的光晕背景
    const gradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, Math.max(width, height) * 0.8
    );
    gradient.addColorStop(0, 'rgba(255, 215, 0, 0.08)');
    gradient.addColorStop(0.3, 'rgba(255, 99, 71, 0.05)');
    gradient.addColorStop(0.6, 'rgba(255, 165, 0, 0.03)');
    gradient.addColorStop(1, 'rgba(220, 20, 60, 0.02)');
    
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    
    // 绘制装饰性的幸运星星（支持动态速度控制）
    const speedMultiplier = this.data.starSpeedMultiplier || 1;
    for (let i = 0; i < 8; i++) {
      const angle = (i / 8) * Math.PI * 2 + Date.now() * 0.0005 * speedMultiplier;
      const radius = 180 + Math.sin(Date.now() * 0.001 + i) * 30;
      const x = centerX + Math.cos(angle) * radius;
      const y = centerY + Math.sin(angle) * radius;
      
      // 移除了多余的参数
      this.drawStar(ctx, x, y, 4 + Math.sin(Date.now() * 0.003 + i) * 2, '#FFD700');
    }
  },

  // 绘制签筒主体
  drawFortuneTubeBody(ctx, centerX, centerY, isShaking) {
    ctx.save();
    
    const tubeWidth = 80;
    const tubeHeight = 160;
    const topRadius = 35;
    
    // 摇动时的旋转效果（增强）
    if (isShaking) {
      const time = Date.now();
      const shakeRotation = Math.sin(time * 0.02) * 0.15;
      ctx.rotate(shakeRotation);
    }
    
    // 绘制签筒阴影（增强立体感）
    const shadowGradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, tubeWidth
    );
    shadowGradient.addColorStop(0, 'rgba(139, 69, 19, 0.4)');
    shadowGradient.addColorStop(1, 'rgba(139, 69, 19, 0)');
    
    ctx.fillStyle = shadowGradient;
    ctx.beginPath();
    ctx.ellipse(centerX, centerY + tubeHeight/2 + 15, tubeWidth/2 + 15, 20, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制签筒主体（竹子颜色，增加光泽效果）
    const tubeGradient = ctx.createLinearGradient(
      centerX - tubeWidth/2, centerY - tubeHeight/2,
      centerX + tubeWidth/2, centerY + tubeHeight/2
    );
    tubeGradient.addColorStop(0, '#DEB887'); // 浅竹色
    tubeGradient.addColorStop(0.3, '#D2B48C'); // 米色
    tubeGradient.addColorStop(0.7, '#CD853F'); // 秘鲁色
    tubeGradient.addColorStop(1, '#A0522D'); // 马鞍棕色
    
    ctx.fillStyle = tubeGradient;
    ctx.fillRect(
      centerX - tubeWidth/2,
      centerY - tubeHeight/2,
      tubeWidth,
      tubeHeight
    );
    
    // 绘制高光效果
    const highlightGradient = ctx.createLinearGradient(
      centerX - tubeWidth/2, centerY - tubeHeight/2,
      centerX - tubeWidth/2 + 25, centerY - tubeHeight/2 + 25
    );
    highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.5)');
    highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
    
    ctx.fillStyle = highlightGradient;
    ctx.fillRect(
      centerX - tubeWidth/2,
      centerY - tubeHeight/2,
      tubeWidth/2.5,
      tubeHeight
    );
    
    // 绘制竹节纹理
    ctx.strokeStyle = '#8B7355';
    ctx.lineWidth = 2;
    for (let i = 1; i < 4; i++) {
      const y = centerY - tubeHeight/2 + (tubeHeight / 4) * i;
      ctx.beginPath();
      ctx.moveTo(centerX - tubeWidth/2, y);
      ctx.lineTo(centerX + tubeWidth/2, y);
      ctx.stroke();
    }
    
    // 绘制签筒顶部（椭圆形，增加光泽）
    const topGradient = ctx.createRadialGradient(
      centerX, centerY - tubeHeight/2, 0,
      centerX, centerY - tubeHeight/2, topRadius
    );
    topGradient.addColorStop(0, '#F5DEB3'); // 小麦色
    topGradient.addColorStop(1, '#D2B48C'); // 米色
    
    ctx.fillStyle = topGradient;
    ctx.beginPath();
    ctx.ellipse(centerX, centerY - tubeHeight/2, topRadius, 15, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制签筒顶部高光
    const topHighlight = ctx.createRadialGradient(
      centerX - 12, centerY - tubeHeight/2 - 7, 0,
      centerX, centerY - tubeHeight/2, topRadius
    );
    topHighlight.addColorStop(0, 'rgba(255, 255, 255, 0.7)');
    topHighlight.addColorStop(1, 'rgba(255, 255, 255, 0)');
    
    ctx.fillStyle = topHighlight;
    ctx.beginPath();
    ctx.ellipse(centerX, centerY - tubeHeight/2, topRadius, 15, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制签筒内部阴影
    ctx.fillStyle = 'rgba(139, 69, 19, 0.4)';
    ctx.beginPath();
    ctx.ellipse(centerX, centerY - tubeHeight/2, topRadius - 5, 12, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制竹签（伸出签筒外，增强动画效果）
    this.drawBambooSticks(ctx, centerX, centerY - tubeHeight/2, topRadius, isShaking);
    
    // 绘制"签"字（增加发光效果）
    this.drawSignCharacter(ctx, centerX, centerY);
    
    // 绘制装饰结（增加光泽）
    this.drawDecorationKnot(ctx, centerX, centerY + tubeHeight/2 - 20);
    
    ctx.restore();
  },

  // 绘制竹签
  drawBambooSticks(ctx, centerX, centerY, radius, isShaking) {
    const stickCount = 15; // 增加竹签数量
    const time = Date.now();
    
    for (let i = 0; i < stickCount; i++) {
      const angle = (i / stickCount) * Math.PI * 2;
      const stickRadius = radius - 8 + Math.random() * 6;
      const stickX = centerX + Math.cos(angle) * (stickRadius * 0.7);
      const stickY = centerY;
      
      let stickHeight = -15 - Math.random() * 25;
      // 增强摇动效果
      if (isShaking) {
        // 更复杂的摇动效果
        const shakeOffset = Math.sin(time * 0.015 + i) * 12;
        stickHeight += shakeOffset;
        
        // 添加摇动时的光晕效果
        const glowRadius = Math.abs(stickHeight) * 0.4;
        const glowGradient = ctx.createRadialGradient(
          stickX, stickY + stickHeight/2, 0,
          stickX, stickY + stickHeight/2, glowRadius
        );
        glowGradient.addColorStop(0, 'rgba(255, 215, 0, 0.4)');
        glowGradient.addColorStop(1, 'rgba(255, 215, 0, 0)');
        
        ctx.fillStyle = glowGradient;
        ctx.beginPath();
        ctx.ellipse(stickX, stickY + stickHeight/2, glowRadius, Math.abs(stickHeight)/2, 0, 0, 2 * Math.PI);
        ctx.fill();
      }
      
      // 绘制单根竹签（增加渐变效果）
      const stickGradient = ctx.createLinearGradient(
        stickX - 1.5, stickY + stickHeight,
        stickX + 1.5, stickY
      );
      stickGradient.addColorStop(0, '#F4A460'); // 沙棕色
      stickGradient.addColorStop(0.5, '#DEB887'); // 浅竹色
      stickGradient.addColorStop(1, '#F4A460'); // 沙棕色
      
      ctx.fillStyle = stickGradient;
      ctx.fillRect(stickX - 1.5, stickY + stickHeight, 3, Math.abs(stickHeight));
      
      // 竹签顶部（增加光泽）
      const topGradient = ctx.createLinearGradient(
        stickX - 2, stickY + stickHeight - 4,
        stickX + 2, stickY + stickHeight
      );
      topGradient.addColorStop(0, '#DEB887');
      topGradient.addColorStop(1, '#F4A460');
      
      ctx.fillStyle = topGradient;
      ctx.fillRect(stickX - 2, stickY + stickHeight - 4, 4, 4);
      
      // 添加竹签上的小装饰点
      if (isShaking && Math.random() > 0.7) {
        ctx.fillStyle = '#8B7355';
        ctx.beginPath();
        ctx.arc(stickX, stickY + stickHeight/3, 0.5, 0, 2 * Math.PI);
        ctx.fill();
      }
    }
  },

  // 绘制“签”字
  drawSignCharacter(ctx, centerX, centerY) {
    // 绘制外发光效果
    ctx.shadowColor = '#FFD700';
    ctx.shadowBlur = 15;
    
    // 绘制金色背景圈
    const bgGradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, 25
    );
    bgGradient.addColorStop(0, '#FFD700');
    bgGradient.addColorStop(0.7, '#FFA500');
    bgGradient.addColorStop(1, '#FF6347');
    
    ctx.fillStyle = bgGradient;
    ctx.beginPath();
    ctx.arc(centerX, centerY, 22, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制边框
    ctx.strokeStyle = '#B8860B';
    ctx.lineWidth = 2;
    ctx.stroke();
    
    // 清除阴影
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    
    // 绘制“签”字（增加发光效果）
    ctx.shadowColor = 'rgba(255, 215, 0, 0.8)';
    ctx.shadowBlur = 5;
    ctx.fillStyle = '#8B0000'; // 深红色
    ctx.font = 'bold 24px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('签', centerX, centerY);
    
    // 清除阴影
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
  },

  // 绘制装饰结
  drawDecorationKnot(ctx, centerX, centerY) {
    // 绘制红色丝带（增加光泽）
    const ribbonGradient = ctx.createLinearGradient(
      centerX - 15, centerY,
      centerX + 15, centerY + 8
    );
    ribbonGradient.addColorStop(0, '#DC143C');
    ribbonGradient.addColorStop(0.5, '#FF6347');
    ribbonGradient.addColorStop(1, '#DC143C');
    
    ctx.fillStyle = ribbonGradient;
    ctx.fillRect(centerX - 15, centerY, 30, 8);
    ctx.fillRect(centerX - 4, centerY - 10, 8, 25);
    
    // 绘制丝带高光
    ctx.fillStyle = '#FF6347';
    ctx.fillRect(centerX - 13, centerY + 1, 26, 2);
    ctx.fillRect(centerX - 2, centerY - 8, 4, 2);
    
    // 添加幸运星装饰
    this.drawLuckyStar(ctx, centerX + 12, centerY - 5, 3);
    this.drawLuckyStar(ctx, centerX - 12, centerY + 3, 3);
  },

  // 绘制签文显示（最上层）
  drawFortuneStick(ctx, centerX, centerY, fortuneText) {
    ctx.save();
    
    // 绘制半透明遮罩（增强视觉效果）
    const maskGradient = ctx.createRadialGradient(
      centerX, centerY, 0,
      centerX, centerY, Math.max(ctx.canvas.width, ctx.canvas.height) / wx.getSystemInfoSync().pixelRatio
    );
    maskGradient.addColorStop(0, 'rgba(0, 0, 0, 0.6)');
    maskGradient.addColorStop(1, 'rgba(0, 0, 0, 0.4)');
    
    ctx.fillStyle = maskGradient;
    ctx.fillRect(0, 0, ctx.canvas.width / wx.getSystemInfoSync().pixelRatio, ctx.canvas.height / wx.getSystemInfoSync().pixelRatio);
    
    // 签条尺寸
    const stickWidth = 300;
    const stickHeight = 70;
    const stickX = centerX - stickWidth / 2;
    const stickY = centerY - stickHeight / 2;
    
    // 绘制签条阴影（增强立体感）
    const shadowGradient = ctx.createLinearGradient(
      stickX, stickY + stickHeight,
      stickX, stickY + stickHeight + 15
    );
    shadowGradient.addColorStop(0, 'rgba(0, 0, 0, 0.4)');
    shadowGradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
    
    ctx.fillStyle = shadowGradient;
    ctx.beginPath();
    ctx.ellipse(centerX, stickY + stickHeight + 5, stickWidth/2 + 10, 10, 0, 0, 2 * Math.PI);
    ctx.fill();
    
    // 绘制签条背景（增加光泽效果）
    const stickGradient = ctx.createLinearGradient(
      stickX, stickY,
      stickX, stickY + stickHeight
    );
    stickGradient.addColorStop(0, '#FFF8DC'); // 粉白色
    stickGradient.addColorStop(0.1, '#FFFACD'); // 柠檀色
    stickGradient.addColorStop(0.5, '#F5DEB3'); // 小麦色
    stickGradient.addColorStop(0.9, '#F5DEB3'); // 小麦色
    stickGradient.addColorStop(1, '#DEB887'); // 浅灰色
    
    ctx.fillStyle = stickGradient;
    // 创建圆角矩形路径
    this.drawRoundedRect(ctx, stickX, stickY, stickWidth, stickHeight, 15);
    ctx.fill();
    
    // 绘制签条边框（增加光泽）
    const borderGradient = ctx.createLinearGradient(
      stickX, stickY,
      stickX, stickY + stickHeight
    );
    borderGradient.addColorStop(0, '#D2691E');
    borderGradient.addColorStop(0.5, '#DEB887');
    borderGradient.addColorStop(1, '#D2691E');
    
    ctx.strokeStyle = borderGradient;
    ctx.lineWidth = 3;
    this.drawRoundedRect(ctx, stickX, stickY, stickWidth, stickHeight, 15);
    ctx.stroke();
    
    // 绘制装饰花纹
    ctx.strokeStyle = '#DAA520';
    ctx.lineWidth = 1.5;
    // 上下装饰线
    ctx.beginPath();
    ctx.moveTo(stickX + 15, stickY + 10);
    ctx.lineTo(stickX + stickWidth - 15, stickY + 10);
    ctx.moveTo(stickX + 15, stickY + stickHeight - 10);
    ctx.lineTo(stickX + stickWidth - 15, stickY + stickHeight - 10);
    ctx.stroke();
    
    // 绘制签文（增强视觉效果）
    ctx.fillStyle = '#8B0000'; // 深红色
    ctx.font = 'bold 18px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 文字阴影效果
    ctx.shadowColor = 'rgba(0, 0, 0, 0.4)';
    ctx.shadowBlur = 3;
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;
    
    // 分行显示长文本
    this.drawWrappedText(ctx, fortuneText, centerX, centerY, stickWidth - 50, 20);
    
    // 绘制顶部装饰星星
    this.drawLuckyStar(ctx, stickX + 20, stickY + 15, 4);
    this.drawLuckyStar(ctx, stickX + stickWidth - 20, stickY + 15, 4);
    
    // 绘制底部装饰星星
    this.drawLuckyStar(ctx, stickX + 20, stickY + stickHeight - 15, 4);
    this.drawLuckyStar(ctx, stickX + stickWidth - 20, stickY + stickHeight - 15, 4);
    
    ctx.restore();
  },

  // 绘制圆角矩形
  drawRoundedRect(ctx, x, y, width, height, radius) {
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
  },

  // 绘制幸运星（用于装饰）
  drawLuckyStar(ctx, centerX, centerY, size) {
    ctx.save();
    ctx.translate(centerX, centerY);
    
    // 绘制金色星星
    const gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, size);
    gradient.addColorStop(0, '#FFFFFF');
    gradient.addColorStop(0.5, '#FFD700');
    gradient.addColorStop(1, '#FFA500');
    
    ctx.fillStyle = gradient;
    ctx.beginPath();
    
    // 五角星的五个顶点
    for (let i = 0; i < 5; i++) {
      const outerAngle = (i * 2 * Math.PI) / 5 - Math.PI / 2;
      const innerAngle = ((i * 2 + 1) * Math.PI) / 5 - Math.PI / 2;
      
      const outerX = Math.cos(outerAngle) * size;
      const outerY = Math.sin(outerAngle) * size;
      const innerX = Math.cos(innerAngle) * (size * 0.5);
      const innerY = Math.sin(innerAngle) * (size * 0.5);
      
      if (i === 0) {
        ctx.moveTo(outerX, outerY);
      } else {
        ctx.lineTo(outerX, outerY);
      }
      ctx.lineTo(innerX, innerY);
    }
    
    ctx.closePath();
    ctx.fill();
    
    // 星星边框
    ctx.strokeStyle = '#B8860B';
    ctx.lineWidth = 1;
    ctx.stroke();
    
    ctx.restore();
  },

  // 分行绘制文字
  drawWrappedText(ctx, text, x, y, maxWidth, lineHeight) {
    const words = text.split('');
    let line = '';
    const lines = [];
    
    // 尝试将文字分成多行
    for (let i = 0; i < words.length; i++) {
      const testLine = line + words[i];
      const metrics = ctx.measureText(testLine);
      
      if (metrics.width > maxWidth && line !== '') {
        lines.push(line);
        line = words[i];
      } else {
        line = testLine;
      }
    }
    lines.push(line);
    
    // 如果行数过多，调整字体大小
    if (lines.length > 2) {
      const fontSize = parseInt(ctx.font.match(/\d+/)[0]);
      ctx.font = ctx.font.replace(/\d+/, fontSize * 0.8);
    }
    
    // 计算起始Y位置以居中显示
    const startY = y - ((lines.length - 1) * lineHeight) / 2;
    
    // 绘制每一行文字
    for (let i = 0; i < lines.length; i++) {
      ctx.fillText(lines[i], x, startY + i * lineHeight);
    }
  },

  // 绘制单个牌子
  drawSingleCard(ctx, card) {
    const { x, y, width, height, isFlipped, content, color } = card;
    
    ctx.save();
    
    // 绘制牌子阴影（更柔和）
    ctx.shadowColor = 'rgba(0, 0, 0, 0.15)';
    ctx.shadowBlur = 8;
    ctx.shadowOffsetX = 3;
    ctx.shadowOffsetY = 3;
    ctx.fillStyle = 'rgba(0, 0, 0, 0.08)';
    ctx.fillRect(x, y, width, height);
    
    if (isFlipped) {
      // 翻开的牌子 - 使用转盘颜色，增加幸运主题效果
      // 绘制渐变背景
      const gradient = ctx.createLinearGradient(x, y, x + width, y + height);
      gradient.addColorStop(0, color);
      gradient.addColorStop(1, this.adjustColorBrightness(color, -30));
      ctx.fillStyle = gradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制高光效果
      const highlightGradient = ctx.createLinearGradient(x, y, x + width * 0.6, y + height * 0.6);
      highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.4)');
      highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
      ctx.fillStyle = highlightGradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制幸运星装饰
      this.drawLuckyStarOnCard(ctx, x + width * 0.15, y + height * 0.15, Math.min(width, height) * 0.1);
      this.drawLuckyStarOnCard(ctx, x + width * 0.85, y + height * 0.85, Math.min(width, height) * 0.1);
      
      // 绘制精美边框
      ctx.strokeStyle = 'rgba(255, 255, 255, 0.9)';
      ctx.lineWidth = 2;
      ctx.strokeRect(x, y, width, height);
      
      // 绘制内容文字（自适应字体大小和换行）
      ctx.fillStyle = '#fff';
      ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
      ctx.shadowBlur = 3;
      ctx.shadowOffsetX = 2;
      ctx.shadowOffsetY = 2;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      
      // 使用新的自适应文字绘制函数
      this.drawAdaptiveTextWithEmojis(ctx, content, x + width / 2, y + height / 2, width * 0.8, height * 0.8);
    } else {
      // 未翻开的牌子 - 优雅的幸运主题设计，但不比翻开的牌更显眼
      // 绘制渐变背景
      const gradient = ctx.createLinearGradient(x, y, x + width, y + height);
      gradient.addColorStop(0, '#a0a0a0'); // 灰色渐变，低调但有质感
      gradient.addColorStop(1, '#808080');
      ctx.fillStyle = gradient;
      ctx.fillRect(x, y, width, height);
      
      // 绘制微妙的纹理效果
      ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
      for (let i = 0; i < 20; i++) {
        const dotX = x + Math.random() * width;
        const dotY = y + Math.random() * height;
        const dotSize = Math.random() * 2;
        ctx.beginPath();
        ctx.arc(dotX, dotY, dotSize, 0, Math.PI * 2);
        ctx.fill();
      }
      
      // 绘制精致边框
      ctx.strokeStyle = '#606060';
      ctx.lineWidth = 1.5;
      ctx.strokeRect(x, y, width, height);
      
      // 绘制幸运问号（使用相对低调的颜色）
      ctx.fillStyle = '#d0d0d0';
      ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
      ctx.shadowBlur = 2;
      ctx.shadowOffsetX = 1;
      ctx.shadowOffsetY = 1;
      ctx.font = `bold ${Math.min(width, height) * 0.4}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('?', x + width / 2, y + height / 2);
      
      // 添加微妙的光效（比之前更低调）
      const lightGradient = ctx.createRadialGradient(
        x + width * 0.3, y + height * 0.3, 0,
        x + width * 0.3, y + height * 0.3, width * 0.4
      );
      lightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.2)');
      lightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
      ctx.fillStyle = lightGradient;
      ctx.fillRect(x, y, width, height);
    }
    
    // 清除阴影设置
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    
    ctx.restore();
  },

  // 绘制幸运星（用于翻牌子）
  drawLuckyStarOnCard(ctx, centerX, centerY, size) {
    ctx.save();
    ctx.translate(centerX, centerY);
    
    // 绘制金色星星
    ctx.fillStyle = 'rgba(255, 215, 0, 0.8)'; // 金色
    ctx.beginPath();
    
    // 五角星的五个顶点
    for (let i = 0; i < 5; i++) {
      const outerAngle = (i * 2 * Math.PI) / 5 - Math.PI / 2;
      const innerAngle = ((i * 2 + 1) * Math.PI) / 5 - Math.PI / 2;
      
      const outerX = Math.cos(outerAngle) * size;
      const outerY = Math.sin(outerAngle) * size;
      const innerX = Math.cos(innerAngle) * (size * 0.5);
      const innerY = Math.sin(innerAngle) * (size * 0.5);
      
      if (i === 0) {
        ctx.moveTo(outerX, outerY);
      } else {
        ctx.lineTo(outerX, outerY);
      }
      ctx.lineTo(innerX, innerY);
    }
    
    ctx.closePath();
    ctx.fill();
    
    // 星星边框
    ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
    ctx.lineWidth = 1;
    ctx.stroke();
    
    ctx.restore();
  },

  // 自适应绘制文字和表情符号（确保都在牌内显示）
  drawAdaptiveTextWithEmojis(ctx, text, x, y, maxWidth, maxHeight) {
    // 提取表情符号和普通文字
    const emojis = this.extractEmojis(text);
    const textWithoutEmojis = this.removeEmojis(text);
    
    // 初始字体大小
    let fontSize = Math.min(maxWidth, maxHeight) * 0.3;
    ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
    
    // 如果只有表情符号
    if (textWithoutEmojis.length === 0 && emojis.length > 0) {
      // 调整表情符号大小以适应区域
      let emojiFontSize = Math.min(maxWidth, maxHeight) * 0.4;
      ctx.font = `${emojiFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      
      // 测量表情符号宽度并调整大小
      let emojiMetrics = ctx.measureText(emojis.join(' '));
      if (emojiMetrics.width > maxWidth) {
        emojiFontSize = emojiFontSize * (maxWidth / emojiMetrics.width);
        ctx.font = `${emojiFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      }
      
      ctx.fillText(emojis.join(' '), x, y);
      return;
    }
    
    // 如果只有文字
    if (emojis.length === 0 && textWithoutEmojis.length > 0) {
      // 测量文字宽度并调整字体大小
      let textMetrics = ctx.measureText(textWithoutEmojis);
      if (textMetrics.width > maxWidth) {
        fontSize = fontSize * (maxWidth / textMetrics.width);
        ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      }
      
      ctx.fillText(textWithoutEmojis, x, y);
      return;
    }
    
    // 同时包含文字和表情符号的情况
    if (textWithoutEmojis.length > 0 && emojis.length > 0) {
      // 分别测量文字和表情符号
      let textMetrics = ctx.measureText(textWithoutEmojis);
      let emojiMetrics = ctx.measureText(emojis.join(' '));
      
      // 计算总宽度并调整字体大小
      const totalWidth = Math.max(textMetrics.width, emojiMetrics.width);
      if (totalWidth > maxWidth) {
        fontSize = fontSize * (maxWidth / totalWidth);
        ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      }
      
      // 重新测量调整后的尺寸
      textMetrics = ctx.measureText(textWithoutEmojis);
      emojiMetrics = ctx.measureText(emojis.join(' '));
      
      // 文字在上，表情符号在下
      const textY = y - fontSize * 0.6;
      const emojiY = y + fontSize * 0.6;
      
      // 绘制文字
      ctx.fillText(textWithoutEmojis, x, textY);
      
      // 绘制表情符号
      const emojiFontSize = fontSize * 1.2;
      ctx.font = `${emojiFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
      ctx.fillText(emojis.join(' '), x, emojiY);
      return;
    }
    
    // 默认情况
    ctx.fillText(text, x, y);
  },

  // 旧的分行绘制文字函数已被删除，使用新的自适应绘制函数替代

  // 处理抽签按钮点击
  onFortuneStart() {
    logInfo('开始抽签');
    
    if (this.data.isShaking) return; // 防止重复点击
    
    // 播放抽签音效
    this.playFortuneSound();
    
    // 开始摇动动画
    this.setData({
      isShaking: true,
      showFortuneStick: false,
      fortuneResult: '',
      // 添加动画参数
      shakeIntensity: 1.0,
      shakeSpeed: 1.0
    });
    
    // 摇动动画持续2秒，逐渐减弱
    const startTime = Date.now();
    const duration = 2000; // 修改为2秒动画时间
    
    const shakeAnimation = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / duration, 1);
      
      // 随着时间推移逐渐减弱摇动强度和速度
      const shakeIntensity = 1.0 - (progress * 0.8);
      const shakeSpeed = 1.0 + (1 - progress) * 2;
      
      this.setData({
        shakeIntensity,
        shakeSpeed
      });
      
      this.drawFortuneTube();
      
      if (progress < 1) {
        // 使用setTimeout模拟requestAnimationFrame获得更流畅的动画
        setTimeout(shakeAnimation, 16); // 约60fps
      }
    };
    
    shakeAnimation();
    
    // 2秒后停止摇动，显示结果
    setTimeout(() => {
      // 修改这里：使用当前转盘的内容进行随机抽取
      let selectedFortune = '';
      
      // 获取当前转盘的项目
      const wheelItems = this.data.wheelItems;
      
      if (wheelItems && wheelItems.length > 0) {
        // 从当前转盘中随机选择一项
        const randomIndex = Math.floor(Math.random() * wheelItems.length);
        const selectedItem = wheelItems[randomIndex];
        
        // 添加幸运鼓励语
        const encouragements = [
          '祝你好运气！',
          '相信自己，你一定可以的！',
          '今天的幸运儿就是你！',
          '愿幸运之神眷顾你！',
          '保持乐观，好事即将发生！',
          '你的努力终将得到回报！',
          '每一天都是新的开始！',
          '相信美好的事情即将发生！'
        ];
        
        const randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)];
        
        // 组合结果和鼓励语
        selectedFortune = '抽中了' + `${selectedItem.text} -- ${randomEncouragement}`;
      } else {
        logError('没有转盘内容');
      }
      
      this.setData({
        isShaking: false,
        fortuneResult: selectedFortune,
        showFortuneStick: true,
        // 重置动画参数
        shakeIntensity: 1.0,
        shakeSpeed: 1.0
      });
      
      // 播放完成音效
      this.playFinishSound();
      
      // 保存历史记录
      this.saveGameHistory('fortune', '幸运抽签', selectedFortune);
      
      // 添加每日首次奖励
      this.addModeReward('fortune', '抽签', 'hasFortuneToday');
      
      // 绘制最终结果
      this.drawFortuneTube();
      
      // 振动反馈
      if (this.data.vibrateEnabled) {
        wx.vibrateShort();
      }
    }, 2000); // 修改为2秒
  },

  // 播放完成音效
  playFinishSound() {
    const { soundEnabled } = this.data;
    
    // 检查全局声音开关
    if (!soundEnabled) {
      logInfo('声音开关已关闭，跳过完成音效播放');
      return;
    }
    
    try {
      // 创建新的音频上下文来支持快速连续播放
      const finishAudioCtx = wx.createInnerAudioContext();
      finishAudioCtx.src = '/audio/finish.mp3';
      finishAudioCtx.loop = false;
      finishAudioCtx.autoplay = false;
      finishAudioCtx.volume = 1.0;
      
      // 播放完成后自动销毁
      finishAudioCtx.onEnded(() => {
        finishAudioCtx.destroy();
      });
      
      finishAudioCtx.onError((err) => {
        logInfo('完成音效播放失败：', err);
        finishAudioCtx.destroy();
        wx.showToast({
          title: '完成音效播放失败',
          icon: 'none',
          duration: 800
        });
      });
      
      // 添加成功监听（可选）
      finishAudioCtx.onPlay(() => {
        logInfo('完成音效播放成功');
      });
      
      // 执行播放
      finishAudioCtx.play();
      
      logInfo('完成音效开始播放');
      
    } catch (error) {
      logError('完成音效播放异常:', error);
    }
  },

  // 关闭签文显示
  closeFortuneStick() {
    this.setData({
      showFortuneStick: false,
      fortuneResult: ''
    });
    this.drawFortuneTube();
  },

  // =================背景动画交互===================
  
  // 触发背景动画效果
  triggerBackgroundAnimation() {
    // 清除之前的定时器
    if (this.data.backgroundAnimationTimer) {
      clearTimeout(this.data.backgroundAnimationTimer);
    }
    
    // 激活动画，星星加速旋转
    this.setData({
      backgroundAnimationActive: true,
      starSpeedMultiplier: 3 // 星星速度加3倍
    });
    
    // 开始循环重绘，创造动画效果
    this.startBackgroundAnimationLoop();
    
    // 2秒后恢复正常速度
    const timer = setTimeout(() => {
      this.setData({
        backgroundAnimationActive: false,
        starSpeedMultiplier: 1,
        backgroundAnimationTimer: null
      });
    }, 2000);
    
    this.setData({
      backgroundAnimationTimer: timer
    });
  },
  
  // 开始背景动画循环
  startBackgroundAnimationLoop() {
    if (!this.data.backgroundAnimationActive) return;
    
    // 根据当前模式重绘胼幕
    const currentMode = this.data.currentMode;
    switch (currentMode) {
      case 'coin':
        this.drawCoin();
        break;

      case 'cards':
        this.drawCards();
        break;
      case 'muyu':
        this.drawMuyu();
        break;
      case 'fortune':
        this.drawFortuneTube();
        break;
    }
    
    // 继续动画循环
    if (this.data.backgroundAnimationActive) {
      setTimeout(() => {
        this.startBackgroundAnimationLoop();
      }, 50); // 20fps的重绘频率
    }
  },
  
  // 抛硬币背景点击处理
  onCoinBackgroundTouch(e) {
    // 如果正在翻转，不处理背景点击
    if (this.data.coinFlipping) return;
    
    logInfo('抛硬币背景被点击');
    this.triggerBackgroundAnimation();
  },

  // 幸运抽签背景点击处理
  onFortuneBackgroundTouch(e) {
    // 注意：与其它模式不同，幸运抽签在摇动时也应该响应背景点击以触发动画
    // 移除了 isShaking 的检查限制
    logInfo('幸运抽签背景被点击');
    this.triggerBackgroundAnimation();
  },

  
  // 翻牌子背景点击处理（但不影响牌子点击）
  onCardsBackgroundTouch(e) {
    // 检查是否点击了牌子区域，如果是则交给原有的牌子点击处理
    const { cardsCtx, cards } = this.data;
    if (!cardsCtx || !cards.length) {
      logInfo('翻牌子背景被点击');
      this.triggerBackgroundAnimation();
      return;
    }
    
    // 获取点击位置
    const query = wx.createSelectorQuery();
    query.select('#cardsCanvas')
      .boundingClientRect((rect) => {
        if (!rect) {
          logInfo('翻牌子背景被点击（无rect）');
          this.triggerBackgroundAnimation();
          return;
        }
        
        const touch = e.touches[0];
        const x = touch.clientX - rect.left;
        const y = touch.clientY - rect.top;
        
        // 检查是否点击了牌子
        const clickedCardIndex = cards.findIndex((card) => {
          return x >= card.x && x <= card.x + card.width &&
                 y >= card.y && y <= card.y + card.height;
        });
        
        if (clickedCardIndex === -1) {
          // 没有点击到牌子，触发背景动画
          logInfo('翻牌子背景被点击（非牌子区域）');
          this.triggerBackgroundAnimation();
        } else {
          // 点击了牌子，交给原有的处理方法
          this.onCardTouch(e);
        }
      })
      .exec();
  },
  
  // 减压敲背景点击处理（但不影响木鱼点击）
  onMuyuBackgroundTouch(e) {
    // 检查是否点击了木鱼或木鱼槌区域
    if (this.data.isKnocking) {
      logInfo('减压敲背景被点击（正在敲击）');
      this.triggerBackgroundAnimation();
      return;
    }
    
    // 获取点击位置并检查是否点击了木鱼区域
    const query = wx.createSelectorQuery();
    query.select('#muyuCanvas')
      .boundingClientRect((rect) => {
        if (!rect) {
          logInfo('减压敲背景被点击（无rect）');
          this.triggerBackgroundAnimation();
          return;
        }
        
        const touch = e.touches[0];
        const canvas = this.data.muyuCanvas;
        const canvasWidth = canvas.width / wx.getSystemInfoSync().pixelRatio;
        const canvasHeight = canvas.height / wx.getSystemInfoSync().pixelRatio;
        
        const x = touch.clientX - rect.left;
        const y = touch.clientY - rect.top;
        
        const centerX = canvasWidth / 2;
        const centerY = canvasHeight / 2;
        
        // 木鱼位置和区域
        const muyuX = centerX;
        const muyuY = centerY + 60;
        const muyuRadius = 70;
        
        // 木鱼槌位置和区域 - 更新为新的位置
        const hammerCenterX = centerX; // 槌头中心对准木鱼中心
        const hammerY = muyuY - 80;
        const hammerTotalWidth = 140;
        const hammerHeight = 40;
        
        // 检查是否点击了木鱼或木鱼槌
        const clickedMuyu = Math.sqrt((x - muyuX) ** 2 + (y - muyuY) ** 2) <= muyuRadius;
        const clickedHammer = x >= (hammerCenterX - hammerTotalWidth/2) && 
                             x <= (hammerCenterX + hammerTotalWidth/2) &&
                             y >= (hammerY - hammerHeight/2) && 
                             y <= (hammerY + hammerHeight/2);
        
        if (clickedMuyu || clickedHammer) {
          // 点击了木鱼或木鱼槌，执行敲击动画
          logInfo('不再敲击');
          // this.performKnockAnimation();
        } else {
          // 点击了背景区域，触发背景动画
          logInfo('减压敲背景被点击（非木鱼区域）');
          this.triggerBackgroundAnimation();
        }
      })
      .exec();
  },
  
  // 重新绘制转盘（页面刷新时调用，复位到初始状态）
  redrawWheel() {
    logInfo('开始重新绘制转盘，复位到初始状态');
    
    // 先同步清除所有状态，确保重绘时使用干净状态
    this.setData({
      resultSectorIndex: -1, // 清除高亮扇区索引
      result: '???',         // 清除结果显示
      rotation: 0,           // 重置旋转角度为0，复位到初始状态
      spinning: false,       // 确保非旋转状态
      showParticles: false,  // 关闭粒子效果
      particles: []          // 清空粒子数组
    });
    
    // 检查是否已有Canvas上下文
    if (this.data.ctx && this.data.wheelItems && this.data.wheelItems.length > 0) {
      // 状态清除后再重新绘制转盘，使用初始旋转角度（0度，表示按创建时的顺序排列）
      // 使用 setTimeout 确保 setData 完成后再绘制
      setTimeout(() => {
        this.drawWheel(0);
        logInfo('转盘重绘完成，扇区已复位到初始顺序，所有状态已清除');
      }, 0);
    } else {
      // 如果没有Canvas上下文或转盘数据，重新创建
      logInfo('Canvas上下文不存在，重新创建');
      this.createCanvasContext();
    }
  },

  // 通用历史记录保存方法
  saveGameHistory(mode, name, result) {
    try {
      const icons = {
        'wheel': '🎯',
        'coin': '🪙',
        'cards': '🃏',
        'fortune': '📜'
      };
      
      const historyItem = {
        mode: mode,
        icon: icons[mode] || '🎯',
        name: name,
        result: result,
        time: new Date().toLocaleString()
      };
      
      let history = wx.getStorageSync('gameHistory') || [];
      history.unshift(historyItem);
      
      // 最多保存50条记录
      if (history.length > 50) {
        history = history.slice(0, 50);
      }
      
      wx.setStorageSync('gameHistory', history);
      logInfo('历史记录保存成功:', historyItem);
    } catch (e) {
      logError('保存历史记录失败', e);
    }
  },

  // 处理导航栏高度变化事件
  onNavHeightChange: function(e) {
    const navHeight = e.detail.navHeight;
    const statusBarHeight = e.detail.statusBarHeight;
    const capsuleButtonInfo = e.detail.capsuleButtonInfo;
    
    this.setData({
      navHeight: navHeight,
      statusBarHeight: statusBarHeight,
      capsuleButtonInfo: capsuleButtonInfo
    });
    
    // 更新页面布局样式
    this.updatePageLayout(navHeight, statusBarHeight, capsuleButtonInfo);
  },

  // 更新页面布局样式
  updatePageLayout: function(navHeight, statusBarHeight, capsuleButtonInfo) {
    // 这里可以添加任何需要根据导航栏高度调整的布局逻辑
    logInfo('导航栏高度更新为:', navHeight);
    logInfo('状态栏高度:', statusBarHeight);
    logInfo('胶囊按钮信息:', capsuleButtonInfo);
  },

  // 转盘专用历史记录保存方法
  saveWheelHistory(wheelId, wheelName, result) {
    try {
      const historyItem = {
        wheelId: wheelId,
        wheelName: wheelName,
        result: result,
        time: new Date().toISOString() // 使用ISO格式便于排序和时间计算
      };
      
      let wheelHistory = wx.getStorageSync('wheelHistory') || [];
      wheelHistory.unshift(historyItem);
      
      // 最多保存50条记录
      if (wheelHistory.length > 50) {
        wheelHistory = wheelHistory.slice(0, 50);
      }
      
      wx.setStorageSync('wheelHistory', wheelHistory);
      logInfo('转盘历史记录保存成功:', historyItem);
    } catch (e) {
      logError('保存转盘历史记录失败', e);
    }
  }
});